Skip to content

Instantly share code, notes, and snippets.

@C47D
Last active January 3, 2018 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save C47D/c9ff884eb49a37f4defc7c82689fe08c to your computer and use it in GitHub Desktop.
Save C47D/c9ff884eb49a37f4defc7c82689fe08c to your computer and use it in GitHub Desktop.
test to send an array of uint8_t's via SPI using both polling and interrupts
#include "project.h"
#include <string.h>
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 */
@C47D
Copy link
Author

C47D commented Dec 30, 2017

Rev. 2: fix typos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment