From bb9df8083eef5b3640a3adff0c6bed73e903ee32 Mon Sep 17 00:00:00 2001 From: "DESKTOP-01T3UKC\\matth" Date: Tue, 28 Aug 2018 11:24:36 -0400 Subject: [PATCH 1/9] link fix for arduino ide setup --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f720a89..242c728 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ This is the base code using by the Mojo V3 to load the FPGA and act as a USB to This code is intended to be used with a modified version of the Arduino IDE. It will not work "out of the box." -See http://embeddedmicro.com/tutorials/mojo/arduino-ide/ for details. \ No newline at end of file +See https://alchitry.com/blogs/tutorials/arduino-ide for details. \ No newline at end of file From 144fc7a7ac10c4b0703b99eb5315bb0022cc04cc Mon Sep 17 00:00:00 2001 From: "DESKTOP-01T3UKC\\matth" Date: Wed, 29 Aug 2018 15:55:41 -0400 Subject: [PATCH 2/9] added eeprom flash and verify functionality to enable custom Look Up Tables to be loaded into the FPGA upon startup via SPI bus --- mojo_loader.ino | 145 ++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 78 deletions(-) diff --git a/mojo_loader.ino b/mojo_loader.ino index 5531e01..d2c4757 100644 --- a/mojo_loader.ino +++ b/mojo_loader.ino @@ -16,6 +16,7 @@ #include "hardware.h" #include "ring_buffer.h" #include +#include #include "flash.h" typedef enum { @@ -24,7 +25,9 @@ typedef enum { WRITE_TO_FLASH, WRITE_TO_FPGA, VERIFY_FLASH, - LOAD_FROM_FLASH + LOAD_FROM_FLASH, + WRITE_TO_EEPROM, + VERIFY_EEPROM } loaderState_t; @@ -45,24 +48,23 @@ taskState_t; uint8_t loadBuffer[BUFFER_SIZE + 128]; -RingBuffer_t adcBuffer, serialBuffer; +RingBuffer_t serialBuffer; volatile taskState_t taskState = SERVICE; -uint8_t adcPort = 0x0F; volatile uint8_t convPort = 0x0F; /* This is where you should add your own code! Feel free to edit anything here. This function will work just like the Arduino loop() function in that it will be called over and over. You should try to not delay too long in the loop to allow the Mojo to enter loading mode when requested. */ +volatile uint8_t sendLUT = 0; + void userLoop() { uartTask(); - adcTask(); } /* this is used to undo any setup you did in initPostLoad */ void disablePostLoad() { - ADCSRA = 0; // disable ADC UCSR1B = 0; // disable serial port SPI.end(); // disable SPI SET(CCLK, LOW); @@ -76,16 +78,9 @@ void disablePostLoad() { void initPostLoad() { //Serial.flush(); - // These buffers are used by the demo ADC/Serial->USB code to prevent dropped samples - RingBuffer_InitBuffer(&adcBuffer, loadBuffer, 128); + // These buffers are used by the Serial->USB code to prevent dropped samples RingBuffer_InitBuffer(&serialBuffer, loadBuffer + 128, BUFFER_SIZE); - - - adcPort = 0x0f; // disable the ADC by default - ADC_BUS_DDR &= ~ADC_BUS_MASK; // make inputs - ADC_BUS_PORT &= ~ADC_BUS_MASK; // no pull ups - // Again, the Arduino libraries didn't offer the functionality we wanted // so we access the serial port directly. This sets up an interrupt // that is used with our own buffer to capture serial input from the FPGA @@ -115,24 +110,11 @@ void initPostLoad() { // the FPGA looks for CCLK to be high to know the AVR is ready for data SET(CCLK, HIGH); IN(CCLK); // set as pull up so JTAG can work -} -/* We needed more flexibility than the Arduino libraries provide. This sets - the ADC up to free-run and call an interrupt when each new sample is ready */ -void configADC(uint8_t preScaler, uint8_t highPower, uint8_t refSelect, uint8_t port) { - ADCSRA = (0 << ADEN); //disable - ADMUX = (refSelect << REFS0) | (port & 0x07); - - if (port > 7) - ADCSRB = (1 << MUX5) | (highPower << ADHSM); - else - ADCSRB = (highPower << ADHSM); - - convPort = port; - ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | (1 << ADIE) - | (preScaler << ADPS0); + loadLUTFromEEPROM(); } + void setup() { /* Disable clock division */ clock_prescale_set(clock_div_1); @@ -179,10 +161,23 @@ void loop() { w = Serial.read(); bt = (uint8_t) w; if (w >= 0) { // if we have data - switch (state) { + + switch (state) { case IDLE: // in IDLE we are waiting for a command from the PC byteCount = 0; transferSize = 0; + if (bt =='T') { // load Look Up Table and verify + state = WRITE_TO_EEPROM; + verify = 1; // verify + transferSize = 1024; + Serial.write('R'); + } + if (bt == 'U' ) { // load Look Up Table and dont verify + state = WRITE_TO_EEPROM; + verify = 0; // verify + transferSize = 1024; + Serial.write('R'); + } if (bt == 'F') { // write to flash destination = 0; // flash verify = 0; // don't verify @@ -204,6 +199,7 @@ void loop() { eraseFlash(); Serial.write('D'); // signal we are done } + //Serial.flush(); break; case READ_SIZE: // we need to read in how many bytes the config data is @@ -268,6 +264,35 @@ void loop() { //Serial.flush(); } break; + + + case WRITE_TO_EEPROM: + // store byte to eeprom + EEPROM.write(byteCount, bt); + + if( ++byteCount == transferSize) { // if we are done + Serial.write('D'); // eeprom write done + + if( verify ){ + state = VERIFY_EEPROM; + } else { + state = LOAD_FROM_FLASH; + } + } + break; + case VERIFY_EEPROM: + if( bt=='P' ){ + do { + Serial.write(EEPROM.read(1024-byteCount)); + delayMicroseconds(100); + } while( --byteCount ); + + state=LOAD_FROM_FLASH; + } + break; + + + case VERIFY_FLASH: if (bt == 'S') { byteCount += 5; @@ -329,62 +354,26 @@ void lineStateEvent(unsigned char linestate) } } -/* This checks to see what port the FPGA is requesting. If it hasn't changed then - no worries, but if it has the ADC needs to be stopped and set to the new port. - - It then empties the ADC buffer into the SPI bus so the FPGA can actually have the - ADC data. */ -void adcTask() { - static uint8_t preScaler = 0x05; // 32 - static uint8_t highPower = 1; - static uint8_t refSelect = 0x01; // AVcc - - uint8_t adc_bus = (ADC_BUS_PIN & ADC_BUS_MASK) >> ADC_BUS_OFFSET; - - if (adc_bus != adcPort) { // did the requested ADC pin change? - adcPort = adc_bus; - if (adcPort < 2 || (adcPort < 10 && adcPort > 3)) { // 0,1,4,5,6,7,8,9 - configADC(preScaler, highPower, refSelect, adcPort); // reconfigure ADC - } - else { // pin is not valid - ADCSRA = (0 << ADEN); //disable ADC - } - } - - while (!RingBuffer_IsEmpty(&adcBuffer)) { // for all the samples - // Grab two bytes from the ring buffer, do it directly for a speed gain - uint8_t byte1 = *adcBuffer.Out; - if (++adcBuffer.Out == adcBuffer.End) - adcBuffer.Out = adcBuffer.Start; - uint8_t byte2 = *adcBuffer.Out; - if (++adcBuffer.Out == adcBuffer.End) - adcBuffer.Out = adcBuffer.Start; - - uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); - GlobalInterruptDisable(); - - adcBuffer.Count -= 2; // actually remove the two bytes from the buffer - - SetGlobalInterruptMask(CurrentGlobalInt); +/* This checks to see if the user on the computer side has requested that the LUT be streamed + * from the AVR to the FPGA over SPI. + */ +void loadLUTFromEEPROM() { + for( int addr=0; addr<1024; addr++ ){ SET(SS, LOW); - uint8_t keyWord = SPI.transfer(byte1); // each sample is two bytes - uint8_t config = SPI.transfer(byte2); + byte a = EEPROM.read(addr); + SPI.transfer(a); SET(SS, HIGH); - if (keyWord == 0xAA) { // the keyWord is used by the FPGA to config the ADC - preScaler = config & 0x07; - highPower = (config >> 3) & 0x01; - refSelect = (config >> 4) & 0x03; - configADC(preScaler, highPower, refSelect, adcPort); - } + delayMicroseconds(1000); } -} -ISR(ADC_vect) { // new ADC sample, save it - RingBuffer_Insert(&adcBuffer, ADCL ); - RingBuffer_Insert(&adcBuffer, (convPort << 4) | ADCH ); } +//ISR(ADC_vect) { // new ADC sample, save it +// RingBuffer_Insert(&adcBuffer, ADCL ); +// RingBuffer_Insert(&adcBuffer, (convPort << 4) | ADCH ); +//} + void serialRXEnable() { UCSR1B |= (1 << RXEN1); } From 56bde564e16441c187305205fd1f389c2294e16a Mon Sep 17 00:00:00 2001 From: Matt Ruffner Date: Tue, 4 Sep 2018 15:38:00 -0400 Subject: [PATCH 3/9] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 242c728..00bdfc2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ +# modifications +- added eeprom upload functionality so fpga can read 1024 non-volatile user programmable bytes upon startup. + This is the base code using by the Mojo V3 to load the FPGA and act as a USB to serial port/ADC for the FPGA. This code is intended to be used with a modified version of the Arduino IDE. It will not work "out of the box." -See https://alchitry.com/blogs/tutorials/arduino-ide for details. \ No newline at end of file +See https://alchitry.com/blogs/tutorials/arduino-ide for details. From 944889f7c623e537c4d2b1322323bb2e9a335889 Mon Sep 17 00:00:00 2001 From: Matt Ruffner Date: Tue, 4 Sep 2018 15:38:20 -0400 Subject: [PATCH 4/9] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 00bdfc2..fbda21f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -# modifications +### modifications - added eeprom upload functionality so fpga can read 1024 non-volatile user programmable bytes upon startup. +### original This is the base code using by the Mojo V3 to load the FPGA and act as a USB to serial port/ADC for the FPGA. This code is intended to be used with a modified version of the Arduino IDE. It will not work "out of the box." From d6a77f3cbcd5c754a737f3be5198b3f8e8168c0a Mon Sep 17 00:00:00 2001 From: "DESKTOP-01T3UKC\\matth" Date: Wed, 10 Oct 2018 20:15:20 -0400 Subject: [PATCH 5/9] added delay before loading lookup table to fpga after initial configuration from spi flash --- mojo_loader.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mojo_loader.ino b/mojo_loader.ino index d2c4757..fab2bb3 100644 --- a/mojo_loader.ino +++ b/mojo_loader.ino @@ -358,13 +358,14 @@ void lineStateEvent(unsigned char linestate) * from the AVR to the FPGA over SPI. */ void loadLUTFromEEPROM() { - + delay(500); for( int addr=0; addr<1024; addr++ ){ + delayMicroseconds(500); SET(SS, LOW); byte a = EEPROM.read(addr); SPI.transfer(a); SET(SS, HIGH); - delayMicroseconds(1000); + delayMicroseconds(500); } } From d90d67808ba1d5a504d43608808a3c79b1b50161 Mon Sep 17 00:00:00 2001 From: Matt Ruffner Date: Tue, 16 Oct 2018 13:03:21 -0400 Subject: [PATCH 6/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fbda21f..266ad77 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ### modifications -- added eeprom upload functionality so fpga can read 1024 non-volatile user programmable bytes upon startup. +- added eeprom upload functionality so fpga can read 1024 non-volatile user programmable bytes upon startup. Jupyter notebook to upload 1024 bytes [here](https://github.com/ruffner/lupa300/tree/master/tools/mojo_trigger). ### original This is the base code using by the Mojo V3 to load the FPGA and act as a USB to serial port/ADC for the FPGA. From 7c6d16a765d3e9fae8b65f053205e6bbcd4f3063 Mon Sep 17 00:00:00 2001 From: Matt Ruffner Date: Tue, 16 Oct 2018 13:03:47 -0400 Subject: [PATCH 7/9] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 266ad77..ef50e96 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ ### modifications -- added eeprom upload functionality so fpga can read 1024 non-volatile user programmable bytes upon startup. Jupyter notebook to upload 1024 bytes [here](https://github.com/ruffner/lupa300/tree/master/tools/mojo_trigger). +- added eeprom upload functionality so fpga can read 1024 non-volatile user programmable bytes upon startup. +- **To Upload** Jupyter notebook to upload 1024 bytes [here](https://github.com/ruffner/lupa300/tree/master/tools/mojo_trigger). ### original This is the base code using by the Mojo V3 to load the FPGA and act as a USB to serial port/ADC for the FPGA. From 7427c59c68b0b814462b7570022a17a055716a6f Mon Sep 17 00:00:00 2001 From: Matt Ruffner Date: Tue, 16 Oct 2018 13:08:45 -0400 Subject: [PATCH 8/9] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ef50e96..dfd7edb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -### modifications -- added eeprom upload functionality so fpga can read 1024 non-volatile user programmable bytes upon startup. +### Changes to Mojo V3 Firmware +- **Custom EEPROM** added eeprom upload functionality so fpga can read 1024 non-volatile user programmable bytes upon startup. - **To Upload** Jupyter notebook to upload 1024 bytes [here](https://github.com/ruffner/lupa300/tree/master/tools/mojo_trigger). +- **At startup** upon FPGA configuration at AVR startup, the 1024 bytes are transferred to the FPGA via SPI. +- **ADC functionality** removed to simplify the use of SPI. ### original This is the base code using by the Mojo V3 to load the FPGA and act as a USB to serial port/ADC for the FPGA. From 8da8c9d74e21aeb49722f08b2c143876cbcd4eba Mon Sep 17 00:00:00 2001 From: "DESKTOP-01T3UKC\\matth" Date: Fri, 1 Mar 2019 15:09:05 -0500 Subject: [PATCH 9/9] updated to version we are currently using on our scanners --- mojo_loader.ino | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/mojo_loader.ino b/mojo_loader.ino index fab2bb3..b72ca7a 100644 --- a/mojo_loader.ino +++ b/mojo_loader.ino @@ -358,16 +358,30 @@ void lineStateEvent(unsigned char linestate) * from the AVR to the FPGA over SPI. */ void loadLUTFromEEPROM() { - delay(500); + byte a; + delay(8000); //standalone project, 700 + for( int addr=0; addr<1024; addr++ ){ - delayMicroseconds(500); + delayMicroseconds(700); SET(SS, LOW); - byte a = EEPROM.read(addr); + a = EEPROM.read(addr); SPI.transfer(a); SET(SS, HIGH); - delayMicroseconds(500); + delayMicroseconds(700); } + delayMicroseconds(600); + SET(SS, LOW); + a = 0x33; + SPI.transfer(a); + SET(SS, HIGH); + delayMicroseconds(600); + SET(SS, LOW); + a = 0x44; + SPI.transfer(a); + SET(SS, HIGH); + delayMicroseconds(600); + } //ISR(ADC_vect) { // new ADC sample, save it