From 168c584b06587322fd9463dcf1b7e1a3740e8e3d Mon Sep 17 00:00:00 2001 From: Juan64Bits Date: Wed, 7 Apr 2010 21:59:30 -0500 Subject: [PATCH] Fixing ADC on high frequency. --- Examples/ADC/QT_src/ADC | Bin 41849 -> 41897 bytes Examples/ADC/QT_src/ADCw.cpp | 23 +- Examples/ADC/QT_src/Makefile | 2 +- Examples/ADC/QT_src/jz47xx_gpio.c | 108 --------- Examples/ADC/QT_src/jz47xx_mmap.c | 39 --- Examples/ADC/QT_src/jz_adc_peripheral.c | 36 --- Examples/ADC/QT_src/jz_adc_peripheral.cpp | 2 +- Examples/ADC/QT_src/jz_adc_peripheral.h | 54 ++--- Examples/ADC/QT_src/jz_test_adc.c | 110 --------- Examples/ADC/QT_src/mainwindow.cpp | 12 +- Examples/ADC/QT_src/signaldisplay.cpp | 8 +- Examples/ADC/logic/ADC_peripheral.v | 276 ++++++++++------------ docs/wiki/.~lock.ADC.odg# | 1 + docs/wiki/ADC.odg | Bin 19643 -> 21356 bytes 14 files changed, 180 insertions(+), 491 deletions(-) delete mode 100644 Examples/ADC/QT_src/jz47xx_gpio.c delete mode 100644 Examples/ADC/QT_src/jz47xx_mmap.c delete mode 100644 Examples/ADC/QT_src/jz_adc_peripheral.c delete mode 100644 Examples/ADC/QT_src/jz_test_adc.c create mode 100644 docs/wiki/.~lock.ADC.odg# diff --git a/Examples/ADC/QT_src/ADC b/Examples/ADC/QT_src/ADC index e7bd47e7dfaedbb2ef9f59604ce934d858c217b3..40ef590362ea3994218080363880dad8963e1671 100755 GIT binary patch delta 5255 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 Mfdc;mZ?N~0f&c&j diff --git a/Examples/ADC/QT_src/ADCw.cpp b/Examples/ADC/QT_src/ADCw.cpp index a1f0f26..07015b5 100644 --- a/Examples/ADC/QT_src/ADCw.cpp +++ b/Examples/ADC/QT_src/ADCw.cpp @@ -13,9 +13,9 @@ ADCw::ADCw() void ADCw::testADC() { /****************Configure ADC register on FPGA RAM memory*****************/ - jz_adc_config(ADCBuffer, 0x01, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_SPI_CLKDIV); + jz_adc_config(ADCBuffer, 0x00, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_SPI_CLKDIV); usleep (1000); - jz_adc_config(ADCBuffer, 0x01, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_FAST_CONV); + jz_adc_config(ADCBuffer, 0x00, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_FAST_CONV); usleep (1000); printf("\nADC in Fast Convertion Mode (10us) and Fs=9.8KHz (Min)\n"); @@ -23,34 +23,37 @@ void ADCw::testADC() /******************************* TEST 1 ***********************************/ printf("\nINIT TEST1: Autoselft {(Vref+) - (Vref-)}/2 -> Return 0x0200 \n"); - jz_adc_config(ADCBuffer, 0x01, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_1); + jz_adc_config(ADCBuffer, 0x00, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_1); + printf("[%08X]", ADCBuffer[0]);fflush (stdout); usleep (1000); jz_adc_config(ADCBuffer, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_READ_AUTOSELFT_1); printf("[%08X]", ADCBuffer[0]);fflush (stdout); while(jz_adc_check_buffer(ADCBuffer)){usleep (10);} - for(int i=1; i< LENB/2+1; i++) + for(int i=1; i< 512; i++) printf("[%08X]", ADCBuffer[i]); fflush (stdout); /******************************* TEST 2 ***********************************/ printf("\n\nINIT TEST2: Autoselft (Vref-) -> Return 0x0000 \n"); - jz_adc_config(ADCBuffer, 0x01, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_2); + jz_adc_config(ADCBuffer, 0x00, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_2); + printf("[%08X]", ADCBuffer[0]);fflush (stdout); usleep (1000); jz_adc_config(ADCBuffer, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_READ_AUTOSELFT_2); printf("[%08X]", ADCBuffer[0]);fflush (stdout); while(jz_adc_check_buffer(ADCBuffer)){usleep (10);} - for(int i=1; i< LENB/2+1; i++) + for(int i=1; i< 512; i++) printf("[%08X]", ADCBuffer[i]); fflush (stdout); /******************************* TEST 3 ***********************************/ printf("\n\nINIT TEST3: Autoselft (Vref+) -> Return 0x03FF \n"); - jz_adc_config(ADCBuffer, 0x01, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_3); + jz_adc_config(ADCBuffer, 0x00, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_3); + printf("[%08X]", ADCBuffer[0]);fflush (stdout); usleep (1000); jz_adc_config(ADCBuffer, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_READ_AUTOSELFT_3); printf("[%08X]", ADCBuffer[0]);fflush (stdout); while(jz_adc_check_buffer(ADCBuffer)){usleep (10);} - for(int i=1; i< LENB/2+1; i++) + for(int i=1; i< 512; i++) printf("[%08X]", ADCBuffer[i]); fflush (stdout); @@ -59,13 +62,13 @@ void ADCw::testADC() void ADCw::powerDownADC() { - jz_adc_config(ADCBuffer, 0x01, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_POWER_DOWN); + jz_adc_config(ADCBuffer, 0x00, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_POWER_DOWN); printf("\nADC in Power Down Mode \n"); } JZ_REG* ADCw::takeSamplesADC(int LENB, uchar CLKDIV, int CHANNEL) { - jz_adc_config(ADCBuffer, 0x01, CLKDIV, ADC_CMD_SET_CHANNEL0+CHANNEL); + jz_adc_config(ADCBuffer, 0x00, CLKDIV, ADC_CMD_SET_CHANNEL0+CHANNEL); usleep (1000); jz_adc_config(ADCBuffer, LENB, CLKDIV, ADC_CMD_READ_CHANNEL0+CHANNEL); //while(jz_adc_check_buffer(ADCBuffer)){usleep (400000);printf("[%08X]", ADCBuffer[0]);fflush (stdout);} diff --git a/Examples/ADC/QT_src/Makefile b/Examples/ADC/QT_src/Makefile index 24936e3..dd3827f 100644 --- a/Examples/ADC/QT_src/Makefile +++ b/Examples/ADC/QT_src/Makefile @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: ADC -# Generated by qmake (2.01a) (Qt 4.6.2) on: Mon Apr 5 13:58:40 2010 +# Generated by qmake (2.01a) (Qt 4.6.2) on: Wed Apr 7 21:11:41 2010 # Project: ADC1.pro # Template: app # Command: /home/juan64bits/ebd/ECB/openwrt-xburst/build_dir/target-mipsel_uClibc-0.9.30.1/qt-everywhere-opensource-src-4.6.2/bin/qmake -spec ../../../../openwrt-xburst/build_dir/target-mipsel_uClibc-0.9.30.1/qt-everywhere-opensource-src-4.6.2/mkspecs/qws/linux-openwrt-g++ -unix -o Makefile ADC1.pro diff --git a/Examples/ADC/QT_src/jz47xx_gpio.c b/Examples/ADC/QT_src/jz47xx_gpio.c deleted file mode 100644 index affa85e..0000000 --- a/Examples/ADC/QT_src/jz47xx_gpio.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - JZ47xx GPIO at userspace - - Copyright (C) 2010 Andres Calderon andres.calderon@emqbit.com - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include -#include -#include - -#include -#include - - -#define JZ_GPIO_BASE 0x10010000 - -void -jz_gpio_as_output (JZ_PIO * pio, unsigned int o) -{ - pio->PXFUNC = (1 << (o)); - pio->PXSELC = (1 << (o)); - pio->PXDIRS = (1 << (o)); -} - -void -jz_gpio_as_input (JZ_PIO * pio, unsigned int o) -{ - pio->PXFUNC = (1 << (o)); - pio->PXSELC = (1 << (o)); - pio->PXDIRC = (1 << (o)); -} - -void -jz_gpio_set_pin (JZ_PIO * pio, unsigned int o) -{ - pio->PXDATS = (1 << (o)); -} - -void -jz_gpio_clear_pin (JZ_PIO * pio, unsigned int o) -{ - pio->PXDATC = (1 << (o)); -} - -void -jz_gpio_out (JZ_PIO * pio, unsigned int o, unsigned int val) -{ - if (val == 0) - pio->PXDATC = (1 << (o)); - else - pio->PXDATS = (1 << (o)); -} - -unsigned int -jz_gpio_get_pin (JZ_PIO * pio, unsigned int o) -{ - return (pio->PXPIN & (1 << o)) ? 1 : 0; -} - -int -jz_gpio_as_func (JZ_PIO * pio, unsigned int o, int func) -{ - switch (func) - { - case 0: - pio->PXFUNS = (1 << o); - pio->PXTRGC = (1 << o); - pio->PXSELC = (1 << o); - return 1; - - case 1: - pio->PXFUNS = (1 << o); - pio->PXTRGC = (1 << o); - pio->PXSELS = (1 << o); - return 1; - - case 2: - pio->PXFUNS = (1 << o); - pio->PXTRGS = (1 << o); - pio->PXSELC = (1 << o); - return 1; - } - return 0; -} - -JZ_PIO * -jz_gpio_map (int port) -{ - JZ_PIO *pio; - - pio = (JZ_PIO *) jz_mmap (JZ_GPIO_BASE); - pio = (JZ_PIO *) ((unsigned int) pio + port * 0x100); - - return pio; -} diff --git a/Examples/ADC/QT_src/jz47xx_mmap.c b/Examples/ADC/QT_src/jz47xx_mmap.c deleted file mode 100644 index e8cf317..0000000 --- a/Examples/ADC/QT_src/jz47xx_mmap.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * JZ47xx GPIO lines - * - * Written 2010 by Andres Calderon andres.calderon@emqbit.com - */ - -#include -#include -#include -#include -#include -#include - -#include - - -void * -jz_mmap (off_t address) -{ - int fd; - - void *pio; - - if ((fd = open ("/dev/mem", O_RDWR | O_SYNC)) == -1) - { - fprintf (stderr, "Cannot open /dev/mem.\n"); - return 0; - } - - pio = (void *) mmap (0, getpagesize (), PROT_READ | PROT_WRITE, MAP_SHARED, fd, address); - - if (pio == (void *) -1) - { - fprintf (stderr, "Cannot mmap.\n"); - return 0; - } - - return pio; -} diff --git a/Examples/ADC/QT_src/jz_adc_peripheral.c b/Examples/ADC/QT_src/jz_adc_peripheral.c deleted file mode 100644 index e5f9cd1..0000000 --- a/Examples/ADC/QT_src/jz_adc_peripheral.c +++ /dev/null @@ -1,36 +0,0 @@ -/* ADC Peripheral.c - -Copyright (C) 2010 Carlos Camargo cicamargoba@unal.edu.co - Andres Calderon andres.calderon@emqbit.com - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include -#include - -#include "jz_adc_peripheral.h" - -void -jz_adc_config(JZ_REG * addr, uchar BUFFER, uchar CLK_DIV, uchar CMD) -{ - addr[0] = (BUFFER << 16) + (CLK_DIV<<8) + CMD; -} - -int -jz_adc_check_buffer(JZ_REG * addr) -{ - return addr[0]&0x00FF0000; -} - diff --git a/Examples/ADC/QT_src/jz_adc_peripheral.cpp b/Examples/ADC/QT_src/jz_adc_peripheral.cpp index 3824f38..9390a3a 100644 --- a/Examples/ADC/QT_src/jz_adc_peripheral.cpp +++ b/Examples/ADC/QT_src/jz_adc_peripheral.cpp @@ -55,5 +55,5 @@ jz_adc_config(JZ_REG * addr, int BUFFER, uchar CLK_DIV, uchar CMD) int jz_adc_check_buffer(JZ_REG * addr) { - return addr[0]&0x00FF0000; + return addr[0]&0x00000010; } diff --git a/Examples/ADC/QT_src/jz_adc_peripheral.h b/Examples/ADC/QT_src/jz_adc_peripheral.h index 6100ad9..d92bff4 100644 --- a/Examples/ADC/QT_src/jz_adc_peripheral.h +++ b/Examples/ADC/QT_src/jz_adc_peripheral.h @@ -26,47 +26,47 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define ADC_CMD_NONE 0x00 /* Nothing to do */ #define ADC_CMD_SET_SPI_CLKDIV 0x90 /* Set clock divider for ADC sclk */ -#define ADC_CMD_SET_CHANNEL0 0x50 /* Set channel 0 */ -#define ADC_CMD_READ_CHANNEL0 0x60 /* Read channel 0 */ +#define ADC_CMD_SET_CHANNEL0 0x30 /* Set channel 0 */ +#define ADC_CMD_READ_CHANNEL0 0x20 /* Read channel 0 */ -#define ADC_CMD_SET_CHANNEL1 0x51 /* Set channel 1 */ -#define ADC_CMD_READ_CHANNEL1 0x61 /* Read channel 1 */ +#define ADC_CMD_SET_CHANNEL1 0x31 /* Set channel 1 */ +#define ADC_CMD_READ_CHANNEL1 0x21 /* Read channel 1 */ -#define ADC_CMD_SET_CHANNEL2 0x52 /* Set channel 2 */ -#define ADC_CMD_READ_CHANNEL2 0x62 /* Read channel 2 */ +#define ADC_CMD_SET_CHANNEL2 0x32 /* Set channel 2 */ +#define ADC_CMD_READ_CHANNEL2 0x22 /* Read channel 2 */ -#define ADC_CMD_SET_CHANNEL3 0x53 /* Set channel 3 */ -#define ADC_CMD_READ_CHANNEL3 0x63 /* Read channel 3 */ +#define ADC_CMD_SET_CHANNEL3 0x33 /* Set channel 3 */ +#define ADC_CMD_READ_CHANNEL3 0x23 /* Read channel 3 */ -#define ADC_CMD_SET_CHANNEL4 0x54 /* Set channel 4 */ -#define ADC_CMD_READ_CHANNEL4 0x64 /* Read channel 4 */ +#define ADC_CMD_SET_CHANNEL4 0x34 /* Set channel 4 */ +#define ADC_CMD_READ_CHANNEL4 0x24 /* Read channel 4 */ -#define ADC_CMD_SET_CHANNEL5 0x55 /* Set channel 5 */ -#define ADC_CMD_READ_CHANNEL5 0x65 /* Read channel 5 */ +#define ADC_CMD_SET_CHANNEL5 0x35 /* Set channel 5 */ +#define ADC_CMD_READ_CHANNEL5 0x25 /* Read channel 5 */ -#define ADC_CMD_SET_CHANNEL6 0x56 /* Set channel 6 */ -#define ADC_CMD_READ_CHANNEL6 0x66 /* Read channel 6 */ +#define ADC_CMD_SET_CHANNEL6 0x36 /* Set channel 6 */ +#define ADC_CMD_READ_CHANNEL6 0x26 /* Read channel 6 */ -#define ADC_CMD_SET_CHANNEL7 0x57 /* Set channel 7 */ -#define ADC_CMD_READ_CHANNEL7 0x67 /* Read channel 8 */ +#define ADC_CMD_SET_CHANNEL7 0x37 /* Set channel 7 */ +#define ADC_CMD_READ_CHANNEL7 0x27 /* Read channel 8 */ -#define ADC_CMD_SET_POWER_DOWN 0X58 /* Set ADC power down mode (1uA) */ +#define ADC_CMD_SET_POWER_DOWN 0X38 /* Set ADC power down mode (1uA) */ -#define ADC_CMD_SET_FAST_CONV 0X59 /* Initialize ADC Fast Convertion(<10us)*/ +#define ADC_CMD_SET_FAST_CONV 0X39 /* Initialize ADC Fast Convertion(<10us)*/ -#define ADC_CMD_SET_LOW_CONV 0X5A /* Initialize ADC Fast Convertion(<40us)*/ +#define ADC_CMD_SET_LOW_CONV 0X3A /* Initialize ADC Fast Convertion(<40us)*/ -#define ADC_CMD_SET_AUTOSELFT_1 0x5B /* Set Autoselft ADC {(Vref+)-(Vref-)}/2*/ -#define ADC_CMD_READ_AUTOSELFT_1 0x6B /* Read Autoselft ADC 1 (0x0200) */ +#define ADC_CMD_SET_AUTOSELFT_1 0x3B /* Set Autoselft ADC {(Vref+)-(Vref-)}/2*/ +#define ADC_CMD_READ_AUTOSELFT_1 0x2B /* Read Autoselft ADC 1 (0x0200) */ -#define ADC_CMD_SET_AUTOSELFT_2 0x5C /* Set Autoselft ADC (Vref-) */ -#define ADC_CMD_READ_AUTOSELFT_2 0x6C /* Read Autoselft ADC 2 (0x0000) */ +#define ADC_CMD_SET_AUTOSELFT_2 0x3C /* Set Autoselft ADC (Vref-) */ +#define ADC_CMD_READ_AUTOSELFT_2 0x2C /* Read Autoselft ADC 2 (0x0000) */ -#define ADC_CMD_SET_AUTOSELFT_3 0x5D /* Set Autoselft ADC (Vref+) */ -#define ADC_CMD_READ_AUTOSELFT_3 0x6D /* Read Autoselft ADC 3 (0x03FF) */ +#define ADC_CMD_SET_AUTOSELFT_3 0x3D /* Set Autoselft ADC (Vref+) */ +#define ADC_CMD_READ_AUTOSELFT_3 0x2D /* Read Autoselft ADC 3 (0x03FF) */ -#define ADC_SPI_CLKDIV_MIN 0x14 /* 50/(2*20) -> 1.25MHz (MAX=2.8MHz) */ -#define ADC_SPI_CLKDIV_MAX 0xFF /* 50/(2*255) -> 98.04KHz */ +#define ADC_SPI_CLKDIV_MIN 0x08 /* 50/(2*9) -> 2.78MHz (MAX=2.8MHz) */ +#define ADC_SPI_CLKDIV_MAX 0xFF /* 50/(2*256) -> 97.65KHz */ #define ADC_MAX_BUFFER 0x3FE/* 1022 reads/commands */ diff --git a/Examples/ADC/QT_src/jz_test_adc.c b/Examples/ADC/QT_src/jz_test_adc.c deleted file mode 100644 index eda939c..0000000 --- a/Examples/ADC/QT_src/jz_test_adc.c +++ /dev/null @@ -1,110 +0,0 @@ -/* ADC TEST - -Copyright (C) 2010 Carlos Camargo cicamargoba@unal.edu.co - Andres Calderon andres.calderon@emqbit.com - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include -#include - -#include "jz47xx_gpio.h" -#include "jz47xx_mmap.h" -#include "jz_adc_peripheral.h" - -#define TEST_PORT JZ_GPIO_PORT_B -#define TEST_PIN 26 - -int -main () -{ - int i,j; - JZ_PIO *pio; - JZ_REG *virt_addr; - - pio = jz_gpio_map (TEST_PORT); - jz_gpio_as_func (pio, TEST_PIN, 0); - - virt_addr = (JZ_REG *) (jz_mmap (0x13010000) + 0x18); - - if (*virt_addr != 0x0FFF7700) - { - *virt_addr = 0x0FFF7700; - printf ("Configuring CS2 32 bits and 0 WS: %08X\n", *virt_addr); - } - else - printf ("CS2, already configured: %08X\n", *virt_addr); - - virt_addr = (JZ_REG *) jz_mmap (0x14000000); - - /*************************Clean FPGA RAM memory****************************/ - for (i = 0; i < 512; i++) //RAMB16_s9_s9 has 2048 bytes 8-bit - { - virt_addr[i] = 0x00000000; //Clean 4 register by cicle - } - - /****************Configure ADC register on FPGA RAM memory*****************/ - uchar LENB = 0x01; // 1 read/cmd - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_SPI_CLKDIV); - usleep (100); - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_FAST_CONV); - usleep (100); - printf("\nADC in Fast Convertion Mode (10us) and Fs=9.8KHz (Min)\n"); - - LENB = ADC_MAX_BUFFER; // 254 read/cmd - - /******************************* TEST 1 ***********************************/ - printf("\nINIT TEST1: Autoselft {(Vref+) - (Vref-)}/2 -> Return 0x0200 \n"); - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_1); - usleep (100); - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_READ_AUTOSELFT_1); - printf("[%08X]", virt_addr[0]); - while(jz_adc_check_buffer(virt_addr)) - { - printf("[%08X]-", virt_addr[0]); - fflush (stdout); - usleep (10000); - } - for(i=1; i< LENB/2+1; i++) - printf("[%08X]", virt_addr[i]); - - /******************************* TEST 2 ***********************************/ - printf("\n\nINIT TEST2: Autoselft (Vref-) -> Return 0x0000 \n"); - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_2); - usleep (100); - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_READ_AUTOSELFT_2); - while(jz_adc_check_buffer(virt_addr)){usleep (100);} - for(i=1; i< LENB/2+1; i++) - printf("[%08X]", virt_addr[i]); - - /******************************* TEST 3 ***********************************/ - printf("\n\nINIT TEST3: Autoselft (Vref+) -> Return 0x03FF \n"); - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_AUTOSELFT_3); - usleep (100); - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_READ_AUTOSELFT_3); - while(jz_adc_check_buffer(virt_addr)){usleep (100);} - for(i=1; i< LENB/2+1; i++) - printf("[%08X]", virt_addr[i]); - - printf("\n\nTESTS complete\n"); - - LENB = 0x01; // 1 read/cmd - jz_adc_config(virt_addr, LENB, ADC_SPI_CLKDIV_MAX, ADC_CMD_SET_POWER_DOWN); - printf("\nADC in Power Down Mode \n"); - - return 0; -} - - diff --git a/Examples/ADC/QT_src/mainwindow.cpp b/Examples/ADC/QT_src/mainwindow.cpp index 246050f..5afe798 100755 --- a/Examples/ADC/QT_src/mainwindow.cpp +++ b/Examples/ADC/QT_src/mainwindow.cpp @@ -10,7 +10,7 @@ MainWindow::MainWindow(QWidget *parent) { ui->setupUi(this); connect(this,SIGNAL(refresh()),ui->Graph, SLOT(repaint())); - ui->Graph->setPointsPerPlot(250); + ui->Graph->setPointsPerPlot(300); ui->Graph->setVoltsPerDiv(102); timer1 = new QTimer(this); @@ -29,16 +29,18 @@ MainWindow::~MainWindow() void MainWindow::updateGraph() { - JZ_REG * dataADC =ADC1->takeSamplesADC(250, 0xFF, 1); + JZ_REG * dataADC =ADC1->takeSamplesADC(300, 0x08, 1); int tempD; - for(int i=1; i< 250/2+1; i++) + for(int i=1; i< 300/2+1; i++) { - tempD = dataADC[i]&0xFFFF; //printf("[%08X]",tempD); + //printf("[%08X]",dataADC[i]); + tempD = dataADC[i]&0xFFFF; ui->Graph->addPoint(tempD); - tempD = dataADC[i]>>16; //printf("[%08X]",tempD); + tempD = dataADC[i]>>16; ui->Graph->addPoint(tempD); } + //printf("\n \n *************************************************************** \n\n"); //fflush (stdout); /*for(int i = 0; i<100;i++) ui->Graph->addPoint(20*sin(6.2832*i/100)+20);*/ diff --git a/Examples/ADC/QT_src/signaldisplay.cpp b/Examples/ADC/QT_src/signaldisplay.cpp index dc6678e..d50868f 100755 --- a/Examples/ADC/QT_src/signaldisplay.cpp +++ b/Examples/ADC/QT_src/signaldisplay.cpp @@ -4,7 +4,7 @@ SignalDisplay::SignalDisplay(QWidget *&parent):QWidget(parent) { - colorTrace = Qt::blue; + colorTrace = Qt::black; secsPerDiv = 1.0/600.0; voltsPerDiv = 20; setPointsPerPlot(10); @@ -34,11 +34,11 @@ void SignalDisplay::paintEvent(QPaintEvent *event){ h = height(); ox = w; oy = h; - painter.fillRect(0,0,w,h,Qt::gray); - painter.setPen(Qt::white); + painter.fillRect(0,0,w,h,Qt::white); + //painter.setPen(Qt::white); //painter.drawLine(secsIdx*w/10/60.0/pointsPerPlot/secsPerDiv,0, \ // secsIdx*w/10/60.0/pointsPerPlot/secsPerDiv,h); - drawGrid(painter, Qt::darkGray,0,0,w,h,4, 10); + drawGrid(painter, Qt::lightGray,0,0,w,h,5, 10); /*for(int i = 0; i < pointsPerPlot; i++) { diff --git a/Examples/ADC/logic/ADC_peripheral.v b/Examples/ADC/logic/ADC_peripheral.v index 7e51522..b28dd13 100644 --- a/Examples/ADC/logic/ADC_peripheral.v +++ b/Examples/ADC/logic/ADC_peripheral.v @@ -10,6 +10,8 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART, output [7:0] rdBus; inout ADC_SDIN, ADC_SDOUT; + reg ADC_CS=1; + //RAMB registers reg [7:0] rdBus; wire [7:0] rdBus1; @@ -18,27 +20,24 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART, reg we1=0; reg we2=0; wire we; - + //Control registers - reg nSample=0; - reg [10:0] auto_count=0; - reg [4:0] w_st2=0; - - - //SPI registers - reg [3:0] SPI_in_data=0; - reg [9:0] SPI_out_data; - reg SPI_rd = 0; - reg SPI_wr = 0; - + reg loadB=0; + reg initB=0; + reg fullB=0; + reg rstStart=0; + reg [2:0] w_st0=0; + reg w_st1=0; + reg [2:0] w_st2=0; + // Confiuration registers - reg CMD_DONE; - reg CMD_TYP; - reg [3:0] CMD_ADC; + reg CMD_START=0; + reg CMD_TYP=0; + reg [3:0] CMD_ADC=0; reg [7:0] CLKDIV = 0; - reg [9:0] SIZEB; //[10:8] -> size_hi | [7:0] -> size_low + reg [9:0] SIZEB=0; //[10:8] -> size_hi | [7:0] -> size_low //TEMPS - reg [9:0] SIZEB2; + reg [9:0] SIZEB2=0; assign ADC_CSTART = 1'b1; @@ -63,77 +62,74 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART, .WEA(we1), // Port A Write Enable Input .WEB(we2) ); // Port B Write Enable Input - // SPI comunication module instantiation + //SPI registers + reg SPI_wr = 0; reg ADC_SCLK_buffer = 0; reg ADC_SDIN_buffer = 0; reg busy = 0, load_in = 0; reg pulse = 0, clkdiv_en = 0; + wire fallingSCLK; reg [3:0] in_buffer=0; reg [9:0] out_buffer; reg [7:0] clkcount = 0; - reg [4:0] count = 0; - reg [4:0] w_st1=0; + reg [5:0] pulsecount = 0; - assign ADC_CS = ~busy; + assign fallingSCLK = pulsecount[0]; - // Clock Generator + // SPI Control + always @(posedge clk) + if(reset) begin + {w_st1, pulsecount, clkdiv_en, busy} <= 0; + end else begin + case (w_st1) + 0: begin + if(SPI_wr) begin + clkdiv_en <= 1; + load_in <= 1; + w_st1 <= 1; busy <= 1; + end + end + 1: begin + load_in <= 0; + if(pulse) + pulsecount <= pulsecount + 1; + else if (pulsecount > 55) begin + clkdiv_en <= 0; busy <= 0; + w_st1 <= 0; pulsecount <= 0; + end + end + endcase + end + + // SPI Clock Generator always@(posedge clk) if (clkdiv_en) begin if(clkcount < CLKDIV) begin clkcount <= clkcount + 1; pulse <=0; end else begin clkcount <= 0; pulse <=1; - if((count>0) && (count < 21)) + if((pulsecount>0) && (pulsecount < 21)) ADC_SCLK_buffer <= ~ADC_SCLK_buffer; end end else begin ADC_SCLK_buffer <= 0; pulse <=0; end - // Control - always @(posedge clk) - if(reset) begin - {w_st1, count, clkdiv_en, busy} <= 0; - end else begin - case (w_st1) - 0: begin - if(SPI_wr) begin - clkdiv_en <= 1; - load_in <= 1; - w_st1 <= 1; busy <= 1; - end - end - 1: begin - load_in <= 0; - if(pulse) - count <= count + 1; - else if (count > 30) begin - clkdiv_en <= 0; busy <= 0; w_st1 <= 0; count <= 0; end - end - endcase - end - // Receptor + // SPI Receptor always@(posedge clk) begin - if((count[0] & pulse) && (count < 21)) begin + if((fallingSCLK & pulse) && (pulsecount < 21)) begin out_buffer <= out_buffer << 1; out_buffer[0] <= ADC_SDOUT; end end - - always@(SPI_rd or out_buffer or busy or CLKDIV) - begin - SPI_out_data <= 10'bx; - if(SPI_rd) - begin SPI_out_data <= out_buffer; end - end - // Transmitter + // SPI Transmitter always@(posedge clk) begin - if(load_in) in_buffer <= SPI_in_data; - if(!count[0] & pulse) begin + if(load_in) in_buffer <= CMD_ADC[3:0]; + if(!fallingSCLK & pulse) begin ADC_SDIN_buffer <= in_buffer[3]; in_buffer <= in_buffer << 1; end @@ -141,86 +137,35 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART, assign ADC_SCLK = ADC_SCLK_buffer; assign ADC_SDIN = ADC_SDIN_buffer; - -/* - assign ADC_CS = ~busy; - always@(SPI_rd or out_buffer or busy or CLKDIV) - begin - SPI_out_data = 10'bx; - if(SPI_rd) - begin SPI_out_data = out_buffer; end - end + /**************************************************************************/ - always@(negedge clk) - begin - if(!busy) - begin - if(SPI_wr) - begin in_buffer = SPI_in_data; busy = 1; end - end - else - begin - clkcount = clkcount + 1; - if(clkcount >= CLKDIV) - begin - clkcount = 0; - // Send the ADC CMD on first 4 rising edge of SCLK - if((count % 2) == 0) - begin - ADC_SDIN_buffer = in_buffer[3]; - in_buffer = in_buffer << 1; - end - // We generate 10 cicles of SCLK - if(count > 0 && count < 21) - begin - ADC_SCLK_buffer = ~ADC_SCLK_buffer; - end - count = count + 1; - if(count > 21) - begin - count = 0; - busy = 0; - end - end - end - end - - always@(posedge ADC_SCLK_buffer) - begin - out_buffer = out_buffer << 1; - out_buffer[0] = ADC_SDOUT; - end - - assign ADC_SCLK = ADC_SCLK_buffer; - assign ADC_SDIN = ADC_SDIN_buffer;*/ - - // Write control + // REGISTER BANK: Write control always @(posedge clk) if(reset) - {CMD_TYP,CMD_ADC,SIZEB,we1} <= 0; + {CMD_START, CMD_TYP,CMD_ADC,SIZEB,we1} <= 0; else if(we & cs) begin case (addr) - 0: begin CMD_TYP <= wrBus[4]; + 0: begin CMD_START <= wrBus[5]; + CMD_TYP <= wrBus[4]; CMD_ADC[3:0] <= wrBus[3:0]; end 1: begin CLKDIV <= wrBus; end 2: begin SIZEB[7:0] <= wrBus; end - 3: begin SIZEB[9:8] <= wrBus[2:0]; end + 3: begin SIZEB[9:8] <= wrBus[1:0]; end default: begin we1 <= 1; end endcase - end - else if(nSample) - begin SIZEB <= SIZEB - 1; end - else - begin we1 <= 0; end + end else if(fullB || rstStart) begin + CMD_START <= 0; end + else begin + we1 <= 0; end - // Read control + // REGISTER BANK: Read control always @(posedge clk) if(reset) {rdBus} <= 0; else begin case (addr) - 0: begin rdBus <= {CMD_DONE,CMD_TYP,CMD_ADC};end + 0: begin rdBus <= {CMD_START,CMD_TYP,CMD_ADC};end 1: begin rdBus <= CLKDIV; end 2: begin rdBus <= SIZEB[7:0]; end 3: begin rdBus <= SIZEB[9:8]; end @@ -228,49 +173,80 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART, endcase end - // Comunication control + // CONTROL + always @(posedge clk) + if(reset) + {w_st0, SPI_wr} <= 0; + else begin + case (w_st0) + 0: begin + rstStart <= 0; loadB <= 0; ADC_CS <=0; initB<=0; + if(CMD_START) begin + initB<=1; + w_st0 <=1; + end + end + 1: begin + SPI_wr <= 1; w_st0 <=2; + end + 2: begin + SPI_wr <= 0; + if(!busy && ADC_EOC) begin + ADC_CS <=1; + if(CMD_TYP) begin + rstStart <= 1; + w_st0<= 0; + end + else begin + loadB <= 1; + w_st0<= 0; + end + end + end + + endcase + end + + // Reception Buffer always @(posedge clk) if(reset) - {we2, SPI_wr, SPI_rd, w_st2, auto_count, SPI_in_data, nSample} <= 0; + {we2, w_st2, fullB, SIZEB2} <= 0; else begin case (w_st2) - 0: begin w_st2 <= 2; SIZEB2<=SIZEB; end - 2: begin - if (SIZEB == 0) - begin w_st2 <= 0; CMD_DONE<= 1; auto_count <= 0; end - else begin - CMD_DONE<= 0; - //Send data to ADC - auto_count <= auto_count+1; - SPI_in_data <= CMD_ADC[3:0]; - SPI_wr <= 1; w_st2 <= 3; + 0: begin + fullB <= 0; + if(initB) begin + w_st2 <= 1; + SIZEB2<=SIZEB; end end - 3: begin - SPI_wr <= 0; - //Wait for complete convertion - if(ADC_CS && ADC_EOC) begin - SPI_rd <=1; - if(CMD_TYP) - w_st2<= 2; - else - w_st2<= 4; - end + 1: begin + if(loadB) begin + // If buffer full set fullB flag by a clock cicle + if(SIZEB2) begin + w_st2 <= 2; end + else begin + fullB <= 1; + w_st2 <= 0; + end + end end - 4: begin + 2: begin //Write data on BRAM (LOW) - wrBus2 <= SPI_out_data[7:0]; + wrBus2 <= out_buffer[7:0]; addr2 <= 4+2*(SIZEB-SIZEB2); - we2 <= 1; w_st2 <= 5; + we2 <= 1; w_st2 <= 3; end - 5: begin we2 <= 0; w_st2 <= 6; end - 6: begin + 3: begin we2 <= 0; w_st2 <= 4; end + 4: begin //Write data on BRAM (HI) - wrBus2 <= SPI_out_data[9:8]; + wrBus2 <= out_buffer[9:8]; addr2 <= 5+2*(SIZEB-SIZEB2); - we2 <= 1; w_st2 <= 7; nSample <= 1; + we2 <= 1; w_st2 <= 5; end - 7: begin nSample <= 0; we2 <= 0; SPI_rd <=0; w_st2 <= 2; end + 5: begin + we2 <= 0; w_st2 <= 1; SIZEB2 <= SIZEB2-1; + end endcase end diff --git a/docs/wiki/.~lock.ADC.odg# b/docs/wiki/.~lock.ADC.odg# new file mode 100644 index 0000000..66c0037 --- /dev/null +++ b/docs/wiki/.~lock.ADC.odg# @@ -0,0 +1 @@ +Juan64Bits ,juan64bits,Maximus,07.04.2010 18:22,file:///home/juan64bits/.openoffice.org/3; \ No newline at end of file diff --git a/docs/wiki/ADC.odg b/docs/wiki/ADC.odg index 9a206d4fce16e5b54cf6c8970ce915a4cfff4a1d..a0afee9e13a5ef50c03fda2c7c14825a185f69d0 100644 GIT binary patch delta 18865 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 delta 17099 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 L!Rl<=JwT!Wd*+w9