1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-01-06 02:20:14 +02:00

Fixing ADC on high frequency.

This commit is contained in:
Juan64Bits 2010-04-07 21:59:30 -05:00
parent f2fb534e32
commit 168c584b06
14 changed files with 180 additions and 491 deletions

Binary file not shown.

View File

@ -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);}

View File

@ -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

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <jz47xx_gpio.h>
#include <jz47xx_mmap.h>
#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;
}

View File

@ -1,39 +0,0 @@
/*
* JZ47xx GPIO lines
*
* Written 2010 by Andres Calderon andres.calderon@emqbit.com
*/
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <jz47xx_mmap.h>
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;
}

View File

@ -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 <stdio.h>
#include <unistd.h>
#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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 <stdio.h>
#include <unistd.h>
#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;
}

View File

@ -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);*/

View File

@ -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++)
{

View File

@ -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

View File

@ -0,0 +1 @@
Juan64Bits ,juan64bits,Maximus,07.04.2010 18:22,file:///home/juan64bits/.openoffice.org/3;

Binary file not shown.