int spi_master_write(spi_t *obj, int value) { TSB_SSP_TypeDef* spi; spi = obj->spi; // Clear all data in transmit FIFO and receive FIFO spi_clear_FIFOs(spi); // Transmit data SSP_SetTxData(spi, value); // Wait for transmitting while (SSP_GetWorkState(spi) == BUSY); // Read received data value = SSP_GetRxData(spi); return value; }
static void spi_clear_FIFOs(TSB_SSP_TypeDef *spi) { SSP_FIFOState tx_buf_state, rx_buf_state; do { while (SSP_GetWorkState(spi) == BUSY); // Get data from receive FIFO SSP_GetRxData(spi); // Check receive FIFO rx_buf_state = SSP_GetFIFOState(spi, SSP_RX); // Check transmit FIFO tx_buf_state = SSP_GetFIFOState(spi, SSP_TX); } while (rx_buf_state != SSP_FIFO_EMPTY || tx_buf_state != SSP_FIFO_EMPTY); }
/* SSP_LoopBack function */ void SSP_LoopBack(void) { SSP_InitTypeDef initSSP; SSP_FIFOState fifoState; uint16_t datTx = 0U; /* must use 16bit type */ uint32_t cntTx = 0U; uint32_t cntRx = 0U; uint16_t receive = 0U; uint16_t Rx_Buf[MAX_BUFSIZE] = { 0U }; uint16_t Tx_Buf[MAX_BUFSIZE] = { 0U }; SystemInit(); /* enable the LED on board to display some info */ UART_Configuration(UART); UART_Print(UART, "This is an example for SSP module!\n\r"); /* configure the SSP module */ initSSP.FrameFormat = SSP_FORMAT_SPI; /* default is to run at maximum bit rate */ initSSP.PreScale = 2U; initSSP.ClkRate = 1U; /* define BITRATE_MIN to run at minimum bit rate */ /* BitRate = fSYS / (PreScale x (1 + ClkRate)) */ #ifdef BITRATE_MIN initSSP.PreScale = 254U; initSSP.ClkRate = 255U; #endif initSSP.ClkPolarity = SSP_POLARITY_LOW; initSSP.ClkPhase = SSP_PHASE_FIRST_EDGE; initSSP.DataSize = 16U; initSSP.Mode = SSP_MASTER; SSP_Init(&initSSP); /* enable loop back mode for self test */ SSP_SetLoopBackMode(ENABLE); /* enable and run SSP module */ SSP_Enable(); while (1) { datTx++; /* send data if Tx FIFO is available */ fifoState = SSP_GetFIFOState(SSP_TX); if ((fifoState == SSP_FIFO_EMPTY) || (fifoState == SSP_FIFO_NORMAL)) { SSP_SetTxData(datTx); if (cntTx < MAX_BUFSIZE) { Tx_Buf[cntTx] = datTx; cntTx++; } else { /* do nothing */ } } else { /* do nothing */ } /* check if there is data arrived */ fifoState = SSP_GetFIFOState(SSP_RX); if ((fifoState == SSP_FIFO_FULL) || (fifoState == SSP_FIFO_NORMAL)) { receive = SSP_GetRxData(); if (cntRx < MAX_BUFSIZE) { Rx_Buf[cntRx] = receive; cntRx++; } else { /* Place a break point here to check if receive data is right. */ /* Success Criteria: */ /* Every data transmited from Tx_Buf is received in Rx_Buf. */ /* When the line "#define BITRATE_MIN" is commented, the SSP is run in maxium */ /* bit rate, so we can find there is enough time to transmit date from 1 to */ /* MAX_BUFSIZE one by one. but if we uncomment that line, SSP is run in */ /* minimum bit rate, we will find that receive data can't catch "datTx++", */ /* in this so slow bit rate, when the Tx FIFO is available, the cntTx has */ /* been increased so much. */ __NOP(); } } else { /* do nothing */ } sprintf(message, "Received data is %d\n\r" + (uint8_t)(receive / 8000)); UART_Print(UART, message); } }
void SSP_LoopBack(void) { SSP_InitTypeDef initSSP; SSP_FIFOState fifoState; uint16_t datTx = 0U; /* must use 16bit type */ uint32_t cntTx = 0U; uint32_t cntRx = 0U; uint16_t receive = 0U; uint16_t Rx_Buf[MAX_BUFSIZE] = { 0U }; uint16_t Tx_Buf[MAX_BUFSIZE] = { 0U }; /* configure the SSP module */ initSSP.FrameFormat = SSP_FORMAT_SPI; /* default is to run at maximum bit rate */ initSSP.PreScale = 2U; initSSP.ClkRate = 1U; /* define BITRATE_MIN to run at minimum bit rate */ /* BitRate = fSYS / (PreScale x (1 + ClkRate)) */ #ifdef BITRATE_MIN initSSP.PreScale = 254U; initSSP.ClkRate = 255U; #endif initSSP.ClkPolarity = SSP_POLARITY_LOW; initSSP.ClkPhase = SSP_PHASE_FIRST_EDGE; initSSP.DataSize = 16U; initSSP.Mode = SSP_MASTER; SSP_Init(TSB_SSP0, &initSSP); /* enable loop back mode for self test */ SSP_SetLoopBackMode(TSB_SSP0, ENABLE); /* enable and run SSP module */ SSP_Enable(TSB_SSP0); /* initialize LEDs on M366-SK board before display something */ GPIO_SetOutput(GPIO_PA,0xFFU); GPIO_WriteData(GPIO_PA,0xFFU); while (1) { datTx++; /* send data if Tx FIFO is available */ fifoState = SSP_GetFIFOState(TSB_SSP0, SSP_TX); if ((fifoState == SSP_FIFO_EMPTY) || (fifoState == SSP_FIFO_NORMAL)) { SSP_SetTxData(TSB_SSP0, datTx); if (cntTx < MAX_BUFSIZE) { Tx_Buf[cntTx] = datTx; cntTx++; } else { /* do nothing */ } } else { /* do nothing */ } /* check if there is data arrived */ fifoState = SSP_GetFIFOState(TSB_SSP0, SSP_RX); if ((fifoState == SSP_FIFO_FULL) || (fifoState == SSP_FIFO_NORMAL)) { receive = SSP_GetRxData(TSB_SSP0); if (cntRx < MAX_BUFSIZE) { Rx_Buf[cntRx] = receive; cntRx++; } else { /* Place a break point here to check if receive data is right. */ /* Success Criteria: */ /* Every data transmited from Tx_Buf is received in Rx_Buf. */ /* When the line "#define BITRATE_MIN" is commented, the SSP is run in maxium */ /* bit rate, so we can find there is enough time to transmit date from 1 to */ /* MAX_BUFSIZE one by one. but if we uncomment that line, SSP is run in */ /* minimum bit rate, we will find that receive data can't catch "datTx++", */ /* in this so slow bit rate, when the Tx FIFO is available, the cntTx has */ /* been increased so much. */ __NOP(); result = Buffercompare(Tx_Buf, Rx_Buf, MAX_BUFSIZE); } } else { /* do nothing */ } DisplayLED(receive); } }