Select Git revision
spipi.cpp 3.37 KiB
#include "spipi.h"
#include <hardware/spi.h>
#include <hardware/gpio.h>
// the relevant functions are here:
// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/pico-sdk/src/ ...
// /rp2040/rp2_common/hardware_spi/include/hardware/spi.h
// the registers we're interested in here:
// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/pico-sdk/src/ ...
// /rp2040/hardware_structs/include/hardware/structs/spi.h
// for earle code reference,
// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/libraries/ ...
// /SPISlave/src/SPISlave.cpp (etc)
// for gpio,
// /jaker/AppData/Local/Arduino15/packages/rp2040/3.6.1/pico-sdk/src/ ...
// /rp2040/rp2_common/hardware_gpio/include/hardware/gpio.h
#define PIN_CS 14
#define PIN_SCK 10
#define PIN_RX 12
#define PIN_TX 11
#define BITRATE 1000000
#define SPI_INST spi1
#define SPI_HW spi_get_hw(SPI_INST)
#define SPI_IMSC_TXIM_ON (1 << 3)
#define SPI_IMSC_RXIM_ON (1 << 2)
#define SPI_IMSC_RTIM_ON (1 << 1)
#define SPI_IMSC_RORIM_ON (1)
volatile uint32_t event_latest = 12;
uint32_t spipi_get_events(void){
return event_latest;
}
// we catch rising edges to delineate packet-end
void spipi_gpio_irq_handler(uint gpio, uint32_t events){
if(gpio_get(PIN_CS)){
gpio_put(1, !gpio_get_out_level(1));
}
// 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_gpio_raw_handler(void){
// gpio_put(1, !gpio_get_out_level(1));
// if(gpio_get_irq_event_mask(PIN_CS) & GPIO_IRQ_EDGE_RISE){
// gpio_acknowledge_irq(PIN_CS, GPIO_IRQ_EDGE_RISE);
// gpio_put(1, !gpio_get_out_level(1));
// }
// }
void spipi_begin(void){
// uh ?
gpio_init(PIN_CS);
gpio_set_dir(PIN_CS, GPIO_IN);
// let's actually just get the CS LOW/HI interrupt first,
// 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_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 ?
// spi_init(SPI_INST, BITRATE);
// spi_set_slave(SPI_INST, true);
// spi_set_format(SPI_INST, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
// assign pins to SPI peripheral,
// gpio_set_function(PIN_CS, GPIO_FUNC_SPI);
// gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
// gpio_set_function(PIN_RX, GPIO_FUNC_SPI);
// gpio_set_function(PIN_TX, GPIO_FUNC_SPI);
// hook up our (one?) interrupt...
// NOTE: changing SPI_INST requires hard-coded change here
// irq_set_exclusive_handler(SPI1_IRQ, spipi_irq_handler);
}
// 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;
// }