Skip to content
Snippets Groups Projects
Commit ffc164c2 authored by Jake Read's avatar Jake Read
Browse files

defeat spi-oddity, transmit and rx data

parent 677bd44b
Branches
No related tags found
No related merge requests found
...@@ -84,3 +84,5 @@ OK, so to see if we can get up to that 10Mbit real-transfer-rate target, I think ...@@ -84,3 +84,5 @@ OK, so to see if we can get up to that 10Mbit real-transfer-rate target, I think
I have hello-worlded this with the Earle Core, but their SPI implementation is strange - since it's simple enough (I'm starting to see that... that's the pint), I'll just roll my own... listening to CS down / up interrupts to frame packets, stuffing buffers, you know the dealio. It's 730pm here but that's just time to put the embedded hardo hat on... I have hello-worlded this with the Earle Core, but their SPI implementation is strange - since it's simple enough (I'm starting to see that... that's the pint), I'll just roll my own... listening to CS down / up interrupts to frame packets, stuffing buffers, you know the dealio. It's 730pm here but that's just time to put the embedded hardo hat on...
I'm going a bit mad with this; I can get GPIO interrupts to fire *just on a falling edge* but not *just on a rising edge* ... I should see if I can access some lower level masks, or something? But it's genuinely sending events *marked* as *rising edge* events on falling and rising edges... I'm going a bit mad with this; I can get GPIO interrupts to fire *just on a falling edge* but not *just on a rising edge* ... I should see if I can access some lower level masks, or something? But it's genuinely sending events *marked* as *rising edge* events on falling and rising edges...
There's another oddity in here... the RP2040 only uses SPI framing where the CS line is pulsed per frame (7-16 bits), so we need to handle it in software, though IDK exactly how to do this as a peripheral, though apparently [this lad](https://github.com/raspberrypi/pico-sdk/issues/88#issuecomment-1402204730) found [a workaround?](https://github.com/uwopus/pico-code/blob/3594e67c1ac34e5454eb4db8362b673bcc7c8862/opus_comms/opus_comms.c#L44-L46) which references 4.4.3.13
\ No newline at end of file
...@@ -4,42 +4,7 @@ ...@@ -4,42 +4,7 @@
// using a (basically raspberry pi pico) W5500-EVB-Pico // using a (basically raspberry pi pico) W5500-EVB-Pico
// with earle philhower core // with earle philhower core
#define PIN_DEBUG 1
// SPI
// SPISettings settings(1000000, MSBFIRST, SPI_MODE0);
uint8_t txBuffer[1024];
volatile uint32_t rxCount = 0;
volatile uint32_t rxSize = 0;
// fires when we get data, I presume ?
// byte rxBuffer[1024];
// this *is unrelated to the CS pin* but should be !
// it actually fires basically every data chunk...
// void onRx(uint8_t* data, size_t len){
// // actually, for the echo we can copy
// // directly across, non ?
// // digitalWrite(PIN_DEBUG, HIGH);
// // memcpy(txBuffer, data, len);
// rxCount ++;
// if(len > rxSize) rxSize = len;
// // shifty shifty
// // digitalWrite(PIN_DEBUG, LOW);
// }
// fires at the end of a transaction ?
// void onTxComplete(void){
// SPISlave1.setData((uint8_t*)txBuffer, 32);
// digitalWrite(PIN_DEBUG, !digitalRead(PIN_DEBUG));
// }
void setup(void){ void setup(void){
// a debug light and pin,
pinMode(PIN_DEBUG, OUTPUT);
digitalWrite(PIN_DEBUG, LOW);
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW); digitalWrite(LED_BUILTIN, LOW);
...@@ -48,26 +13,6 @@ void setup(void){ ...@@ -48,26 +13,6 @@ void setup(void){
// the spi setup // the spi setup
spipi_begin(); spipi_begin();
// fill our demo buffer
for(uint16_t i = 0; i < 1024; i ++){
txBuffer[i] = i;
}
// SPISlave1.setData((uint8_t*)txBuffer, 32);
// // pin config (2040 GPIO Nums)
// SPISlave1.setCS(13);
// SPISlave1.setSCK(10);
// SPISlave1.setRX(12);
// SPISlave1.setTX(11);
// // callbacks
// SPISlave1.onDataRecv(onRx);
// SPISlave1.onDataSent(onTxComplete);
// // startup
// SPISlave1.begin(settings);
} }
uint32_t lastUpdate = 0; uint32_t lastUpdate = 0;
...@@ -77,9 +22,9 @@ void loop(void){ ...@@ -77,9 +22,9 @@ void loop(void){
if(lastUpdate + updateInterval < millis()){ if(lastUpdate + updateInterval < millis()){
lastUpdate = millis(); lastUpdate = millis();
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
displayPrint(String(rxCount) + "\n" + displayPrint(spipi_print());
String(rxSize) + "\n" + // displayPrint(String(rxCount) + "\n" +
String(spipi_get_events()) // String(rxSize)
); // );
} }
} }
\ No newline at end of file
...@@ -18,8 +18,9 @@ ...@@ -18,8 +18,9 @@
// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/pico-sdk/src/ ... // /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/pico-sdk/src/ ...
// /rp2040/rp2_common/hardware_gpio/include/hardware/gpio.h // /rp2040/rp2_common/hardware_gpio/include/hardware/gpio.h
#define PIN_DEBUG 1
#define PIN_CS 14 #define PIN_CS 13
#define PIN_SCK 10 #define PIN_SCK 10
#define PIN_RX 12 #define PIN_RX 12
#define PIN_TX 11 #define PIN_TX 11
...@@ -34,79 +35,89 @@ ...@@ -34,79 +35,89 @@
#define SPI_IMSC_RTIM_ON (1 << 1) #define SPI_IMSC_RTIM_ON (1 << 1)
#define SPI_IMSC_RORIM_ON (1) #define SPI_IMSC_RORIM_ON (1)
// some static buffs
uint8_t rxBuffer[255];
volatile uint8_t rxPtr = 0;
String spipi_print(void){
volatile uint32_t event_latest = 12; return String(rxBuffer[0]) + ", " + String(rxBuffer[1]);
uint32_t spipi_get_events(void){
return event_latest;
} }
uint8_t txBuffer[255];
volatile uint8_t txPtr = 0;
volatile uint8_t txLen = 32;
// we catch rising edges to delineate packet-end // we catch rising edges to delineate packet-end
void spipi_gpio_irq_handler(uint gpio, uint32_t events){ void spipi_gpio_irq_handler(uint gpio, uint32_t events){
if(gpio_get(PIN_CS)){ if(gpio_get(PIN_CS)){
gpio_put(1, !gpio_get_out_level(1)); txPtr = 0;
rxPtr = 0;
// gpio_put(PIN_DEBUG, !gpio_get_out_level(PIN_DEBUG));
} }
// event_latest = events;
// if(events & GPIO_IRQ_EDGE_RISE){
// gpio_put(1, !gpio_get_out_level(1));
// } else if (events & GPIO_IRQ_EDGE_FALL){
// // gpio_put(1, !gpio_get_out_level(1));
// }
} }
void spipi_irq_handler(void){
// void spipi_gpio_raw_handler(void){ gpio_put(PIN_DEBUG, !gpio_get_out_level(PIN_DEBUG));
// gpio_put(1, !gpio_get_out_level(1)); // both have up to 8 bytes to read / write per interrupt ?
// if(gpio_get_irq_event_mask(PIN_CS) & GPIO_IRQ_EDGE_RISE){ // get bytes while readable,
// gpio_acknowledge_irq(PIN_CS, GPIO_IRQ_EDGE_RISE); for(uint8_t c = 0; c < 8; c ++){
// gpio_put(1, !gpio_get_out_level(1)); if(spi_is_readable(SPI_INST) && rxPtr < txLen){
// } rxBuffer[rxPtr] = SPI_HW->dr;
// } rxPtr ++;
}
}
// write bytes while writable
for(uint8_t c = 0; c < 8; c ++){
if(spi_is_writable(SPI_INST) && txPtr < txLen){
SPI_HW->dr = txBuffer[txPtr];
txPtr ++;
}
}
// rx
// if we're out of data, we could turn interrupts off w/ this:
// i.e. *just* turning the RX-interrupt on... ??
// SPI_HW->imsc = 0 | SPI_IMSC_RXIM_ON;
}
void spipi_begin(void){ void spipi_begin(void){
// dummy pin
gpio_init(PIN_DEBUG);
gpio_set_dir(PIN_DEBUG, GPIO_OUT);
// dummy buffer
for(uint8_t i = 0; i < 255; i ++){
txBuffer[i] = i;
}
// uh ? // uh ?
gpio_init(PIN_CS); gpio_init(PIN_CS);
gpio_set_dir(PIN_CS, GPIO_IN); gpio_set_dir(PIN_CS, GPIO_IN);
// let's actually just get the CS LOW/HI interrupt first, // let's actually just get the CS LOW/HI interrupt first,
// so we can reset our buffer states (etc) // so we can reset our buffer states (etc)
// gpio_set_irq_enabled_with_callback(PIN_CS, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, false, &spipi_gpio_irq_handler);
gpio_set_irq_enabled_with_callback(PIN_CS, GPIO_IRQ_EDGE_RISE, true, &spipi_gpio_irq_handler); gpio_set_irq_enabled_with_callback(PIN_CS, GPIO_IRQ_EDGE_RISE, true, &spipi_gpio_irq_handler);
// gpio_set_input_hysteresis_enabled(PIN_CS, false); // gpio_set_input_hysteresis_enabled(PIN_CS, false);
// or this simpler handler-thing ?
// gpio_set_irq_enabled(PIN_CS, GPIO_IRQ_EDGE_RISE, true);
// gpio_add_raw_irq_handler(PIN_CS, &spipi_gpio_raw_handler);
// startup the peripheral ? // startup the peripheral ?
// spi_init(SPI_INST, BITRATE); spi_init(SPI_INST, BITRATE);
// spi_set_slave(SPI_INST, true); spi_set_slave(SPI_INST, true);
// spi_set_format(SPI_INST, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); // spi_set_format(SPI_INST, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
// oddity where mode 0b11 allow continuous CS_LOW ?
// that's right, folks, we can only do this with 0b11 mode, insane:
// see https://github.com/raspberrypi/pico-sdk/issues/88#issuecomment-1402204730
// and see RP2040 datasheet at 4.4.3.13 !
spi_set_format(SPI_INST, 8, SPI_CPOL_1, SPI_CPHA_1, SPI_MSB_FIRST);
// assign pins to SPI peripheral, // assign pins to SPI peripheral,
// gpio_set_function(PIN_CS, GPIO_FUNC_SPI); // gpio_set_function(PIN_CS, GPIO_FUNC_SPI);
// gpio_set_function(PIN_SCK, GPIO_FUNC_SPI); gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
// gpio_set_function(PIN_RX, GPIO_FUNC_SPI); gpio_set_function(PIN_RX, GPIO_FUNC_SPI);
// gpio_set_function(PIN_TX, GPIO_FUNC_SPI); gpio_set_function(PIN_TX, GPIO_FUNC_SPI);
// hook up our (one?) interrupt... // hook up our (one?) interrupt...
// NOTE: changing SPI_INST requires hard-coded change here // NOTE: changing SPI_INST requires hard-coded change here
// irq_set_exclusive_handler(SPI1_IRQ, spipi_irq_handler); SPI_HW->imsc = SPI_IMSC_RXIM_ON | SPI_IMSC_TXIM_ON;
irq_set_exclusive_handler(SPI1_IRQ, &spipi_irq_handler);
irq_set_enabled(SPI1_IRQ, true);
} }
// void spipi_irq_handler(void){
// // both have up to 8 bytes to read / write per interrupt ?
// // get bytes while readable,
// if(spi_is_readable(SPI_INST)){
// uint8_t byte = SPI_HW->dr;
// }
// // write bytes while writable
// if(spi_is_writable(SPI_INST)){
// SPI_HW->dr = 85;
// }
// // if we're out of data, we could turn interrupts off w/ this:
// // i.e. *just* turning the RX-interrupt on... ??
// SPI_HW->imsc = 0 | SPI_IMSC_RXIM_ON;
// }
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
#include <Arduino.h> #include <Arduino.h>
void spipi_begin(void); void spipi_begin(void);
uint32_t spipi_get_events(void); String spipi_print(void);
#endif #endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment