Platform/ECM3532/M3/hw/csp/ecm3532/m3/csp/src/eta_csp_spi.c
/***************************************************************************/
/**
 *
 * EtaCspSpiTransferPoll - Read and or write to an SPI device.
 *
 * @param iNum SPI instance number
 * @param pui8TxData Pointer to the data to transmit.
 * @param ui32TxLen Transmit length in bytes.
 * @param pui8RxData Point to the received data.
 * @param ui32RxLen Receive length in bytes.
 * @param spiChipSel Chip Select to use
 * @param iSpiSequence Sequence field allowing multiple functions in a single SPI command
 * @return Return the status.
 *
 ******************************************************************************/
Read and or write to an SPI device.
@param iNum SPI instance number
@param pui8TxData Pointer to the data to transmit.
@param ui32TxLen Transmit length in bytes.
@param pui8RxData Point to the received data.
@param ui32RxLen Receive length in bytes.
@param spiChipSel Chip Select to use
@param iSpiSequence Sequence field allowing multiple functions in a single SPI command
@return Return the status.
Read and or write to an SPI device . @param iNum SPI instance number @param pui8TxData Pointer to the data to transmit . @param ui32TxLen Transmit length in bytes . @param pui8RxData Point to the received data . @param ui32RxLen Receive length in bytes . @param spiChipSel Chip Select to use @param iSpiSequence Sequence field allowing multiple functions in a single SPI command @return Return the status .
tEtaStatus
EtaCspSpiTransferPoll(tSpiNum iNum, uint8_t *pui8TxData, uint32_t ui32TxLen,
                       uint8_t *pui8RxData, uint32_t ui32RxLen,
                       tSpiChipSel spiChipSel, tSpiSequence iSpiSequence)
{
  tEtaStatus localStatus;
  uint32_t ui32Timeout;
  uint8_t tx_byte;
  uint8_t rx_byte;
  if (ui32TxLen > (64*1024)-1)
  {
#ifdef ETA_CSP_SPI_DEBUG
    ETA_DIAGS_PRINTF ("ERROR: EtaCspSpiTransferPoll for iNum=%d exceeded max ui32TxLen of (64*1024)-1 with %d", iNum, ui32TxLen);
#endif
    return eEtaSpiInvalidConfig;
  }
  if (ui32RxLen > (64*1024)-1)
  {
#ifdef ETA_CSP_SPI_DEBUG
    ETA_DIAGS_PRINTF ("ERROR: EtaCspSpiTransferPoll for iNum=%d exceeded max ui32RxLen of (64*1024)-1 with %d", iNum, ui32RxLen);
#endif
    return eEtaSpiInvalidConfig;
  }
  if ((iNum == eSpi1) && ((spiChipSel == eSpiChipSel2) || (spiChipSel == eSpiChipSel3)))
  {
#ifdef ETA_CSP_SPI_DEBUG
    ETA_DIAGS_PRINTF ("ERROR: EtaCspSpiTransferPoll for iNum=%d invalid chipselect", iNum, spiChipSel);
#endif
    return eEtaSpiInvalidConfig;
  }
  if (iSpiSequence & eSpiSequenceFirstOnly)
  {
    if ( ( localStatus = EtaCspSpiDonePoll(iNum) ) )
      return localStatus;
    REG_SPI_STATUS(iNum).V = BM_SPI_STATUS_START_BUSY | (spiChipSel<<BP_SPI_STATUS_CS_SEL) | BM_SPI_STATUS_HOLD_CS;
  }
  REG_SPI_RXDROP_CNT(iNum).V = ui32TxLen;
  ui32Timeout=10000;
  while ((--ui32Timeout) && (ui32TxLen))
  {
    if ( ( localStatus = EtaCspSpiTxReadyPoll(iNum) ) )
      return localStatus;
    tx_byte = *pui8TxData++;
    REG_SPI_TXRX_1BYTE_FIFO_DATA(iNum).V = tx_byte;
    ui32TxLen--;
  }
  if (ui32Timeout == 0) return 1;
  REG_SPI_TX_DUMMY_BYTE_CNT(iNum).V = ui32RxLen;
  if (iSpiSequence & eSpiSequenceLastOnly)
  {
    REG_SPI_STATUS(iNum).V = 0;
  }
  ui32Timeout=10000;
  while ((--ui32Timeout) && (ui32RxLen))
  {
    localStatus = EtaCspSpiRxDataPoll(iNum);
    if (localStatus)
      return localStatus;
    rx_byte = REG_SPI_TXRX_1BYTE_FIFO_DATA(iNum).V;
    *pui8RxData++ = rx_byte;
    ui32RxLen --;
  }
  if (ui32Timeout == 0)
    return(eEtaFailure);
  return (eEtaSuccess);
}
tEtaStatus EtaCspSpiTransferPoll ( tSpiNum iNum , uint8_t * pui8TxData , uint32_t ui32TxLen , uint8_t * pui8RxData , uint32_t ui32RxLen , tSpiChipSel spiChipSel , tSpiSequence iSpiSequence ) { tEtaStatus localStatus ; uint32_t ui32Timeout ; uint8_t tx_byte ; uint8_t rx_byte ; if ( ui32TxLen > ( 64 * 1024 ) - 1 ) { #ifdef ETA_CSP_SPI_DEBUG ETA_DIAGS_PRINTF ( " " , iNum , ui32TxLen ) ; #endif return eEtaSpiInvalidConfig ; } if ( ui32RxLen > ( 64 * 1024 ) - 1 ) { #ifdef ETA_CSP_SPI_DEBUG ETA_DIAGS_PRINTF ( " " , iNum , ui32RxLen ) ; #endif return eEtaSpiInvalidConfig ; } if ( ( iNum == eSpi1 ) && ( ( spiChipSel == eSpiChipSel2 ) || ( spiChipSel == eSpiChipSel3 ) ) ) { #ifdef ETA_CSP_SPI_DEBUG ETA_DIAGS_PRINTF ( " " , iNum , spiChipSel ) ; #endif return eEtaSpiInvalidConfig ; } if ( iSpiSequence & eSpiSequenceFirstOnly ) { if ( ( localStatus = EtaCspSpiDonePoll ( iNum ) ) ) return localStatus ; REG_SPI_STATUS ( iNum ) . V = BM_SPI_STATUS_START_BUSY | ( spiChipSel << BP_SPI_STATUS_CS_SEL ) | BM_SPI_STATUS_HOLD_CS ; } REG_SPI_RXDROP_CNT ( iNum ) . V = ui32TxLen ; ui32Timeout = 10000 ; while ( ( -- ui32Timeout ) && ( ui32TxLen ) ) { if ( ( localStatus = EtaCspSpiTxReadyPoll ( iNum ) ) ) return localStatus ; tx_byte = * pui8TxData ++ ; REG_SPI_TXRX_1BYTE_FIFO_DATA ( iNum ) . V = tx_byte ; ui32TxLen -- ; } if ( ui32Timeout == 0 ) return 1 ; REG_SPI_TX_DUMMY_BYTE_CNT ( iNum ) . V = ui32RxLen ; if ( iSpiSequence & eSpiSequenceLastOnly ) { REG_SPI_STATUS ( iNum ) . V = 0 ; } ui32Timeout = 10000 ; while ( ( -- ui32Timeout ) && ( ui32RxLen ) ) { localStatus = EtaCspSpiRxDataPoll ( iNum ) ; if ( localStatus ) return localStatus ; rx_byte = REG_SPI_TXRX_1BYTE_FIFO_DATA ( iNum ) . V ; * pui8RxData ++ = rx_byte ; ui32RxLen -- ; } if ( ui32Timeout == 0 ) return ( eEtaFailure ) ; return ( eEtaSuccess ) ; }
EtaCspSpiTransferPoll - Read and or write to an SPI device.
EtaCspSpiTransferPoll - Read and or write to an SPI device .
// If it is first, start command // Make sure previous command is done (optional) // Start command // Deal with TX first // We'll drop ui32TxLen of data (garbage receive data during TX) // Now deal with RX. // Write number of dummy bytes to send to get rx data we want // If it is Last, end command // At this point, all TX is in the queue. Remove hold // 1 Byte version // pop data off the read stack // If we have data to send, ignore receive data. // This ui32Timeout is for general programming reasons to prevent infinite loop