void spi_xfer_rw(spi_desc_t *desc, uint8_t *wdata, int wlen, uint8_t *rdata, int rlen) { int i; int len = max(wlen, rlen); uint8_t last_wdata = wdata[wlen-1]; uint8_t rd_byte; /* Drain any outstanding request */ spi_xfer_wait(desc); for (i = 0; i < len; i++) { /* Wait for TXFIFO to have space */ while (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_TNF) != SET) ; /* Clear all remaining frames in RX FIFO */ while (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_RNE)) { rd_byte = Chip_SSP_ReceiveFrame(desc->spi_dev); --desc->n_outstanding; if (rlen > 0) { *rdata++ = rd_byte; --rlen; } } Chip_SSP_SendFrame(desc->spi_dev, (i < wlen) ? *wdata++ : last_wdata); ++desc->n_outstanding; } /* Wait for TXFIFO to drain */ while (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_TFE) != SET) ; while (rlen > 0) { if (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_RNE) == SET) { rd_byte = Chip_SSP_ReceiveFrame(desc->spi_dev); --desc->n_outstanding; *rdata++ = rd_byte; --rlen; } } }
/* SSP Polling Read/Write in blocking mode */ uint32_t Chip_SSP_RWFrames_Blocking(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup) { /* Clear all remaining frames in RX FIFO */ while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) { Chip_SSP_ReceiveFrame(pSSP); } /* Clear status */ Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK); if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) { while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) { /* write data to buffer */ if (( Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) { SSP_Write2BFifo(pSSP, xf_setup); } /* Check overrun error */ if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) { return ERROR; } /* Check for any data available in RX FIFO */ SSP_Read2BFifo(pSSP, xf_setup); } } else { while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) { /* write data to buffer */ if (( Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) { SSP_Write1BFifo(pSSP, xf_setup); } /* Check overrun error */ if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) { return ERROR; } /* Check for any data available in RX FIFO */ SSP_Read1BFifo(pSSP, xf_setup); } } if (xf_setup->tx_data) { return xf_setup->tx_cnt; } else if (xf_setup->rx_data) { return xf_setup->rx_cnt; } return 0; }
void spi_xfer_wait(spi_desc_t *desc) { /* Wait for TXFIFO to drain */ while (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_TFE) != SET) ; while (desc->n_outstanding > 0) { if (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_RNE) == SET) { Chip_SSP_ReceiveFrame(desc->spi_dev); --desc->n_outstanding; } } }
/** SSP macro: read 2 bytes from FIFO buffer */ STATIC void SSP_Read1BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup) { uint16_t rDat; while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) && (xf_setup->rx_cnt < xf_setup->length)) { rDat = Chip_SSP_ReceiveFrame(pSSP); if (xf_setup->rx_data) { *(uint8_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat; } xf_setup->rx_cnt++; } }
/* Clean all data in RX FIFO of SSP */ void Chip_SSP_Int_FlushData(LPC_SSP_T *pSSP) { if (Chip_SSP_GetStatus(pSSP, SSP_STAT_BSY)) { while (Chip_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {} } /* Clear all remaining frames in RX FIFO */ while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) { Chip_SSP_ReceiveFrame(pSSP); } /* Clear status */ Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK); }
void spi_xfer_wr_byte(spi_desc_t *desc, uint8_t wdata) { /* Wait for TXFIFO to have space */ while (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_TNF) != SET) ; /* Clear all remaining frames in RX FIFO */ while (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_RNE)) { Chip_SSP_ReceiveFrame(desc->spi_dev); --desc->n_outstanding; } Chip_SSP_SendFrame(desc->spi_dev, wdata); ++desc->n_outstanding; }
uint8_t spi_xfer_rw_byte(spi_desc_t *desc, uint8_t wdata) { uint8_t rd_byte; spi_xfer_wait(desc); spi_xfer_wr_byte(desc, wdata); while (1) { if (Chip_SSP_GetStatus(desc->spi_dev, SSP_STAT_RNE) == SET) { rd_byte = Chip_SSP_ReceiveFrame(desc->spi_dev); --desc->n_outstanding; break; } } return rd_byte; }
/* SSP Polling Read in blocking mode */ uint32_t Chip_SSP_ReadFrames_Blocking(LPC_SSP_T *pSSP, uint8_t *buffer, uint32_t buffer_len) { uint32_t rx_cnt = 0, tx_cnt = 0; /* Clear all remaining frames in RX FIFO */ while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) { Chip_SSP_ReceiveFrame(pSSP); } /* Clear status */ Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK); if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) { uint16_t *rdata16; rdata16 = (uint16_t *) buffer; while (tx_cnt < buffer_len || rx_cnt < buffer_len) { /* write data to buffer */ if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) { Chip_SSP_SendFrame(pSSP, 0xFFFF); /* just send dummy data */ tx_cnt += 2; } /* Check overrun error */ if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) { return ERROR; } /* Check for any data available in RX FIFO */ while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) { *rdata16 = Chip_SSP_ReceiveFrame(pSSP); rdata16++; rx_cnt += 2; } } } else { uint8_t *rdata8; rdata8 = buffer; while (tx_cnt < buffer_len || rx_cnt < buffer_len) { /* write data to buffer */ if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) { Chip_SSP_SendFrame(pSSP, 0xFF); /* just send dummy data */ tx_cnt++; } /* Check overrun error */ if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) { return ERROR; } /* Check for any data available in RX FIFO */ while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) { *rdata8 = Chip_SSP_ReceiveFrame(pSSP); rdata8++; rx_cnt++; } } } return rx_cnt; }