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

earle core spi implementation is whack, we r finna go baremetal spi

parent cff2fdc5
Branches
No related tags found
No related merge requests found
*__pycache__
*.vscode
*build
\ No newline at end of file
......@@ -80,3 +80,5 @@ We are normally pulling one byte at a time - if we want to be catching while we
### SPI Echo Code
OK, so to see if we can get up to that 10Mbit real-transfer-rate target, I think I will start with an echo test - since SPI is transfer-based anyways (we always send data when we get it), I'll program some arduino to get packets and echo them, and we'll turn the speed up until we start making mistakes.
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...
\ No newline at end of file
import spidev
bitrate = 50000000
bitrate = 1000000
print(f'rate {bitrate/1e6}MBit/s bit period should be {1000000000/bitrate}ns')
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = bitrate
spi.mode = 0b00
for i in range(1000000):
spi.xfer([12, 14, 95])
test_pck = bytearray(32)
for b in range(len(test_pck)):
test_pck[b] = b
print(test_pck)
for i in range(1000):
ret = spi.xfer(test_pck)
print(ret)
spi.close()
\ No newline at end of file
#include <SPI.h>
#include <SPISlave.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
// WARNING
/*
this basically doesn't work: Earle Core treats SPI transfers
like UART, i.e. it does minimal listening to CS pin to delineate packets
oddball stuff, I'm set to write it barebones...
*/
#define PIN_DEBUG 0
// OLED
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define X_POS 0
#define Y_POS 0
#define TXT_SIZE 1
// even for displays with i.e. "0x78" printed on the back,
// the address that works is 0x3C, IDK
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1);
// warning: is blocking, takes ~ 33ms !
void displayPrint(String msg){
display.clearDisplay();
display.setCursor(X_POS, Y_POS);
display.print(msg);
display.display();
}
void displaySetup(void){
Wire1.setSDA(2);
Wire1.setSCL(3);
// initialize the screen,
// oddly, SWITCHCAPVCC is the option that works even though OLED is hooked to 5V
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.clearDisplay();
display.display();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(TXT_SIZE);
display.setTextWrap(true);
display.dim(false);
displayPrint("bonjour...");
}
// 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){
// a debug light and pin,
pinMode(PIN_DEBUG, OUTPUT);
digitalWrite(PIN_DEBUG, LOW);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
// the display setup
displaySetup();
// 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 updateInterval = 200;
void loop(void){
if(lastUpdate + updateInterval < millis()){
lastUpdate = millis();
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
displayPrint(String(rxCount) + "\n" + String(rxSize));
}
}
\ 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