-/*
+/*
* Humusoft MF624 DAQ card implementation
- *
+ *
* Copyright (C) 2011 Rostislav Lisovy (lisovy@gmail.com)
- *
+ *
* Licensed under GPLv2 license
*/
#include "hw.h"
#include "qemu-thread.h"
#include <string.h>
#include <unistd.h>
-#include <sys/types.h>
+#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define INTCSR_off 0x4C
#define GPIOC_off 0x54
-/* BAR2 */
+/* BAR2 */
#define ADDATA_off 0x00
#define ADCTRL_off 0x00
#define ADDATA1_off 0x02
uint32_t port;
int addr;
- /* The real voltage which is on inputs od A/D convertors.
- Until new conversion is started, there is still old value in ADC registers*/
+ /* The real voltage which is on inputs od A/D convertors.
+ Until new conversion is started, there is still old value in ADC registers*/
unsigned int real_world_AD0; //Value in "ADC internal" format
unsigned int real_world_AD1;
unsigned int real_world_AD2;
unsigned int BAR0_mem_table_index;
unsigned int BAR2_mem_table_index;
unsigned int BAR4_mem_table_index;
-
+
// Internal registers values
BAR0_t BAR0;
BAR2_t BAR2;
BAR4_t BAR4;
- int ADDATA_FIFO[8]; //this array tells us which ADCs are being converted
- unsigned int ADDATA_FIFO_POSITION; //ADDATA is FIFO register;
+ int ADDATA_FIFO[8]; //this array tells us which ADCs are being converted
+ unsigned int ADDATA_FIFO_POSITION; //ADDATA is FIFO register;
//We need to know, position in this FIFO =
//Which value will come next
} mf624_state_t;
//Initialize all registers to default values
s->BAR0.INTCSR = INTCSR_default_value;
- s->BAR0.GPIOC = GPIOC_default_value;
+ s->BAR0.GPIOC = GPIOC_default_value;
s->BAR2.ADDATA = 0x0;
s->BAR2.ADCTRL = 0x0;
s->BAR2.ADDATA1 = 0x0;
perror("read()");
return;
}
-
+
if (received_length == 0) {
printf("Error while reading from socket. Client disconnected?\n");
return;
}
else {
printf("reg = %s; val = %f\n", reg, val);
- }
+ }
}
}
}
struct sockaddr_in addr_srv;
int port;
int yes = 1;
-
+
mf624_state_t* dev = (mf624_state_t*) ptr;
dev->socket_tmp = -1;
perror("socket()");
return NULL;
}
-
+
if (setsockopt(dev->socket_srv, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt()");
return NULL;
perror("bind()");
return NULL;
}
-
+
if (listen(dev->socket_srv, 5) == -1) {
perror("listen()");
return NULL;
}
printf("Client connected\n");
-
- socket_read(dev); // should run forever if everything is OK;
+
+ socket_read(dev); // should run forever if everything is OK;
// If error occurs (client disconnected), returns here
-
+
close(dev->socket_tmp);
}
s->BAR0.INTCSR = (value & 0x7FF) | INTCSR_default_value; // Only first 11 bits are writable
socket_write(s, "INTCSR", s->BAR0.INTCSR);
break;
-
+
case GPIOC_off:
//Don't write anywhere else than into these two bits
s->BAR0.GPIOC = (value & (GPIOC_LDAC_mask | GPIOC_DACEN_mask)) | GPIOC_default_value;
socket_write(s, "DA6", dacinternal_to_volts(s->BAR2.DA6));
socket_write(s, "DA7", dacinternal_to_volts(s->BAR2.DA7));
}
-
+
//Is output forced to GND?
if (!(s->BAR0.GPIOC & GPIOC_DACEN_mask))
{
socket_write(s, "DA7", dacinternal_to_volts(GND));
}
break;
-
+
default:
printf("mf624_BAR0_write32(): addr = " TARGET_FMT_plx "; value = %d\n", addr, value);
break;
s->ADDATA_FIFO_POSITION = i; // Move to next AD to be read
}
}
-
+
switch (s->ADDATA_FIFO_POSITION)
{
case 0:
case ADSTART_off:
s->BAR0.GPIOC |= GPIOC_EOLC_mask; // Conversion in progress
s->ADDATA_FIFO_POSITION = 0;
- for (i = 0; i < 5000; i++)
+ for (i = 0; i < 5000; i++)
; // Small delay simulating real conversion
// Check before assignement, if particular ADC is enabled
s->BAR2.ADDATA5 = (s->BAR2.ADCTRL & (1 << 5)) ? s->real_world_AD5 : s->BAR2.ADDATA5;
s->BAR2.ADDATA6 = (s->BAR2.ADCTRL & (1 << 6)) ? s->real_world_AD6 : s->BAR2.ADDATA6;
s->BAR2.ADDATA7 = (s->BAR2.ADCTRL & (1 << 7)) ? s->real_world_AD7 : s->BAR2.ADDATA7;
-
+
//All channels converted
s->BAR0.GPIOC &= ~ GPIOC_EOLC_mask;
-
+
return 0xFFFF; // Semirandom value
default:
case DA1_off:
s->BAR2.DA1 = value;
- if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
+ if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
(s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
socket_write(s, "DA1", dacinternal_to_volts(s->BAR2.DA1));
}
case DA2_off:
s->BAR2.DA2 = value;
- if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
+ if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
(s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
socket_write(s, "DA2", dacinternal_to_volts(s->BAR2.DA2));
}
case DA3_off:
s->BAR2.DA3 = value;
- if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
+ if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
(s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
socket_write(s, "DA3", dacinternal_to_volts(s->BAR2.DA3));
}
case DA4_off:
s->BAR2.DA4 = value;
- if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
+ if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
(s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
socket_write(s, "DA4", dacinternal_to_volts(s->BAR2.DA4));
}
case DA5_off:
s->BAR2.DA5 = value;
- if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
+ if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
(s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
socket_write(s, "DA5", dacinternal_to_volts(s->BAR2.DA5));
}
case DA6_off:
s->BAR2.DA6 = value;
- if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
+ if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
(s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
socket_write(s, "DA6", dacinternal_to_volts(s->BAR2.DA6));
}
case DA7_off:
s->BAR2.DA7 = value;
- if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
+ if (!(s->BAR0.GPIOC & GPIOC_LDAC_mask) &&
(s->BAR0.GPIOC & GPIOC_DACEN_mask)) {
socket_write(s, "DA7", dacinternal_to_volts(s->BAR2.DA7));
}
NULL, /* read16 */
mf624_BAR0_read32,
};
-
+
static CPUWriteMemoryFunc * const mf624_BAR0_write[3] = {
NULL, /* write8 */
NULL, /* write16 */
mf624_BAR2_read16,
NULL, /* read32 */
};
-
+
static CPUWriteMemoryFunc * const mf624_BAR2_write[3] = {
NULL, /* write8 */
mf624_BAR2_write16,
NULL, /* read16 */
mf624_BAR4_read32,
};
-
+
static CPUWriteMemoryFunc * const mf624_BAR4_write[3] = {
NULL, /* write8 */
NULL, /* write16 */
//-----------------------------------------------------------------------------
-
+
static void mf624_map(PCIDevice *pci_dev, int region_num,
pcibus_t addr, pcibus_t size, int type)
{