#include "project.h" #include enum { MAX_ITEMS = 10, }; typedef enum { TX_IDLE, TX_TRANSFERING, } tx_state_tag; volatile tx_state_tag tx_state = TX_IDLE; typedef struct { uint8_t buffer[MAX_ITEMS]; uint8_t cnt; uint8_t left_to_xfer; } buffer_t; #define DEFAULT_BUFFER_T {.buffer = {0}, .cnt = 0, .left_to_xfer = 0} buffer_t tx_buffer = DEFAULT_BUFFER_T; void spi_xfer_asynch(const uint8_t *data, const size_t size); void SPI_tx_handler(void); int main(void) { const uint8_t data_spi[10] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}; // SPI_tx_handler is a callback executed when we receive 1 byte isr_SPI_Tx_StartEx(SPI_tx_handler); // Enable interrupts CyGlobalIntEnable; // Configure and enable the peripherals SPI_Start(); UART_Start(); UART_PutChar(0x0C); // clear the screen UART_PutString("Test SPI with interrupts.\r\n"); while (1) { if (TX_IDLE == tx_state) { spi_xfer_asynch(data_spi, 3); } CyDelayUs(10); LED_Write(~LED_Read()); } } void spi_xfer_asynch(const uint8_t *data, const size_t size) { CyGlobalIntDisable; if (TX_IDLE == tx_state) { tx_state = TX_TRANSFERING; if (size <= SPI_FIFO_SIZE) { SS_Write(0); // fill the spi tx fifo (4 bytes depth) for (uint8_t i = 0; i < size; i++) { SPI_WriteTxData(data[i]); } } else { tx_buffer.cnt = 0; tx_buffer.left_to_xfer = size - SPI_FIFO_SIZE; memcpy(tx_buffer.buffer, &data[SPI_FIFO_SIZE], tx_buffer.left_to_xfer); SS_Write(0); // fill the spi tx fifo for (uint8_t i = 0; i < SPI_FIFO_SIZE; i++) { SPI_WriteTxData(data[i]); } } } CyGlobalIntEnable; } void SPI_tx_handler(void) { // clear interrupt flag by reading the SPI_TX_STS register volatile uint8_t sts = SPI_ReadTxStatus(); // TODO: Get the data from MISO (void)SPI_ReadRxStatus(); if (TX_IDLE != tx_state) { if (SPI_STS_BYTE_COMPLETE & sts) { if (TX_IDLE != tx_state) { // do we still have data to send? if (tx_buffer.left_to_xfer > tx_buffer.cnt) { SPI_WriteTxData(tx_buffer.buffer[tx_buffer.cnt]); tx_buffer.cnt++; } } else { // we shouldn't get in here } } // the interrupt was triggered by the SPI_DONE flag // the SPI_IDLE flag is set to 0 when data is detected on the TX FIFO // SPI_IDLE set to 1 is the default state of the SPI state machine, if (SPI_STS_SPI_IDLE & sts) { // we're done, set the /SS line high SS_Write(1); tx_state = TX_IDLE; } } } /* [] END OF FILE */