]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Fixed bugs in DAC setting. Added function for setting ADCs. Tested. Working -- only...
authorRostislav Lisovy <lisovy@gmail.com>
Thu, 7 Apr 2011 21:31:43 +0000 (23:31 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Thu, 7 Apr 2011 21:31:43 +0000 (23:31 +0200)
src/uio/mf624/userspace/test_application/main.c

index 0e94f1e773738021e3e3776bbe589e84fbb118ac..daed9b4cc80843520d9e9c7e38a399d38df2804c 100755 (executable)
 #define min(a, b)              ((a) > (b) ? (b) : (a))
 
 /* Hardware specific */
+/* BAR0 */
 #define GPIOC_reg              0x54
+
+/* BAR2 */
+#define ADCTRL_reg             0x00
+#define ADDATA0_reg            0x00
+#define ADDATA1_reg            0x02
+#define ADDATA2_reg            0x04
+#define ADDATA3_reg            0x06
+#define ADDATA4_reg            0x08
+#define ADDATA5_reg            0x0a
+#define ADDATA6_reg            0x0c
+#define ADDATA7_reg            0x0e
+#define ADSTART_reg            0x20
+
 #define DOUT_reg               0x10
+#define DIN_reg                0x10
 #define DA0_reg                        0x20
 #define DA1_reg                        0x22
 #define DA2_reg                        0x24
 #define DA6_reg                        0x2C
 #define DA7_reg                        0x2E
 
+
+
 #define GPIOC_DACEN_mask       (1 << 26)
 #define GPIOC_LDAC_mask                (1 << 23)       
+#define GPIOC_EOLC_mask                (1 << 17)
 
 #define BAR0_offset            (0 * sysconf(_SC_PAGESIZE))
 #define BAR2_offset            (1 * sysconf(_SC_PAGESIZE))
 #define BAR4_offset            (2 * sysconf(_SC_PAGESIZE))
 
-typedef enum {DA0, DA1} dac_channel_t;
+
+typedef enum {DA0, DA1, DA2, DA3, DA4, DA5, DA6, DA7} dac_channel_t;
+typedef enum {AD0, AD1, AD2, AD3, AD4, AD5, AD6, AD7} adc_channel_t;
+
 
 int status;
 void* mf624_BAR0 = NULL;
@@ -42,7 +63,10 @@ void* mf624_BAR4 = NULL;
 int BAR0_phys_addr;
 int BAR2_phys_addr;
 int BAR4_phys_addr;
+int ADC_enabled; // Which ADCs are enabled 
 
+
+/* Print one byte as binary number */
 void print_8bin(int nr)
 {
        int i;
@@ -79,15 +103,16 @@ void DIO_write(int16_t val)
 
 uint16_t DIO_read()
 {
-       return mf624_read16(mf624_BAR2 + DOUT_reg) & 0xF; 
+       return mf624_read16(mf624_BAR2 + DIN_reg) & 0xF; 
 }
 
 void DAC_enable()
 {
-       mf624_write16(mf624_read16(mf624_BAR2 + GPIOC_reg) 
-               | GPIOC_DACEN_mask 
-               & ~GPIOC_LDAC_mask, 
-               mf624_BAR2 + GPIOC_reg); 
+       // Setting DACEN and LDAC bits in GPIO register influences all DACs
+       mf624_write32((mf624_read32(mf624_BAR0 + GPIOC_reg) 
+               | GPIOC_DACEN_mask) // enable output 
+               & ~GPIOC_LDAC_mask, // enable conversion
+               mf624_BAR0 + GPIOC_reg); 
 }
 
 void DAC_write(dac_channel_t channel, int val) {
@@ -98,14 +123,88 @@ void DAC_write(dac_channel_t channel, int val) {
                case DA1:
                        mf624_write16(val, mf624_BAR2 + DA1_reg); 
                        break;
+               case DA2:
+                       mf624_write16(val, mf624_BAR2 + DA2_reg); 
+                       break;
+               case DA3:
+                       mf624_write16(val, mf624_BAR2 + DA3_reg); 
+                       break;
+               case DA4:
+                       mf624_write16(val, mf624_BAR2 + DA4_reg); 
+                       break;
+               case DA5:
+                       mf624_write16(val, mf624_BAR2 + DA5_reg); 
+                       break;
+               case DA6:
+                       mf624_write16(val, mf624_BAR2 + DA6_reg); 
+                       break;
+               case DA7:
+                       mf624_write16(val, mf624_BAR2 + DA7_reg); 
+                       break;
                default:
                        printf("FFFUUU!\n");
        }
+}
+
+void ADC_enable(adc_channel_t channel)
+{
+       ADC_enabled = 0;
 
+       switch (channel) {
+               case AD0:
+                       ADC_enabled = (1 << 0);
+                       break;
+               case AD1:
+                       ADC_enabled = (1 << 1);
+                       break;
+               case AD2:
+                       ADC_enabled = (1 << 2);
+                       break;
+               case AD3:
+                       ADC_enabled = (1 << 3);
+                       break;
+               case AD4:
+                       ADC_enabled = (1 << 4);
+                       break;
+               case AD5:
+                       ADC_enabled = (1 << 5);
+                       break;
+               case AD6:
+                       ADC_enabled = (1 << 6);
+                       break;
+               case AD7:
+                       ADC_enabled = (1 << 7);
+                       break;
+               default:
+                       printf("FFFUUU!\n");
+       }
        
+       ADC_enabled &= 0xFF;
+       mf624_write16(ADC_enabled, mf624_BAR2 + ADCTRL_reg);
+       //print_8bin(ADC_enabled);
+}
+
+/* This function blocks until conversion is finished */
+double ADC_read(adc_channel_t channel)
+{
+       int i;
+       int result;
+
+       // Activate trigger to start conversion
+       mf624_read16(mf624_BAR2 + ADSTART_reg); 
+
+       // Check if conversion has finished
+       while((mf624_read32(mf624_BAR0 + GPIOC_reg) & GPIOC_EOLC_mask)) {       
+               for (i = 0; i < 1000; i++) {} // small wait
+       }
+
+       ADC_enable(channel);
+       result = mf624_read16(mf624_BAR2 + ADDATA0_reg);
 
+       return 10.0 * ((int16_t) (result << 2)) / (double) 0x8000;
 }
 
+
 int open_device(char* path) {
        status = open(path, O_RDWR);
        if (status == -1) {
@@ -278,8 +377,6 @@ void mmap_regions(int device_fd, char* uio_dev)
        fclose(file);
 
 
-       //FIXME size of memory must be in multiples of memory pages
-       // size = (size + PAGE_SIZE -1) / PAGE_SIZE * PAGE_SIZE; ?
        mf624_BAR0 = mmap(0, 1 * sysconf(_SC_PAGESIZE), PROT_READ | PROT_WRITE, MAP_SHARED, device_fd, BAR0_offset);
        if (mf624_BAR2 == MAP_FAILED) {
                perror("mmap()");
@@ -332,16 +429,23 @@ int main(int argc, char* argv[])
        if (device_fd != -1) {
                DAC_enable();
 
-
                while (1){
-                       printf("Reading DIO = ");
+                       printf("Reading DIO: ");
                        print_8bin(DIO_read());
                        sleep(1);
-       
-                       printf("Setting DA0 to 10 V\n");
-                       DAC_write(DA0, 0x3FFF);
+
+                       printf("Setting DA1 to 10 V\n");
+                       DAC_write(DA1, 0x3FFF);
                        sleep(1);
 
+                       printf("Reading ADC0: ");
+                       printf("%f V\n", ADC_read(AD0));
+                       sleep(1);
+       
+                       printf("Reading ADC1: ");
+                       printf("%f V\n", ADC_read(AD1));
+                       sleep(1);
+       
                        printf("Setting DIO to 0xff\n");
                        DIO_write(0xff);
                        sleep(1);
@@ -350,10 +454,17 @@ int main(int argc, char* argv[])
                        DIO_write(0x00);
                        sleep(1);
 
-                       printf("Setting DA0 to 5 V\n");
-                       DAC_write(DA0, 0x3000);
+                       printf("Setting DA1 to 5 V\n");
+                       DAC_write(DA1, 0x3000);
                        sleep(1);
                        
+                       printf("Reading ADC0: ");
+                       printf("%f V\n", ADC_read(AD0));
+                       sleep(1);
+       
+                       printf("Reading ADC1: ");
+                       printf("%f V\n", ADC_read(AD1));
+                       sleep(1);
                        printf("----------------------\n\n");
                }
        }