// -----------------------------------------------------------------------------
//! \brief      This routine initializes and begins a SPI transaction
//!
//! \param[in]  len - Number of bytes to write.
//!
//! \return     uint8 - number of bytes written to transport
// -----------------------------------------------------------------------------
uint16 NPITLSPI_writeTransport(uint16 len)
{
    int16 i = 0;
    ICall_CSState key;
    
    key = ICall_enterCriticalSection();

    TransportTxBufLen = len + SPI_TX_FIELD_LEN;
    
    // Shift TX message two bytes to give room for SPI header
    for( i = ( TransportTxBufLen - 1 ) ; i >= 0 ; i-- )
    {
      TransportTxBuf[i + SPI_TX_HDR_LEN] = TransportTxBuf[i];
    }
    
    // Add header (including a zero padding byte required by the SPI driver)
    TransportTxBuf[SPI_TX_ZERO_PAD_INDEX] = 0x00;
    TransportTxBuf[SPI_TX_SOF_INDEX] = SPI_SOF;
    TransportTxBuf[SPI_TX_LEN_INDEX] = len;
    
    // Calculate and append FCS at end of Frame
    TransportTxBuf[TransportTxBufLen - 1] = 
        NPITLSPI_calcFCS(&TransportTxBuf[SPI_TX_LEN_INDEX],len + 1);

    // Clear DMA Rx buffer and clear extra Tx buffer bytes to ensure clean buffer
    //    for next RX/TX
    memset(TransportRxBuf, 0, NPI_TL_BUF_SIZE);
    memset(&TransportTxBuf[TransportTxBufLen], 0, NPI_TL_BUF_SIZE - TransportTxBufLen);

    // set up the SPI Transaction
    spiTransaction.count = NPI_TL_BUF_SIZE;
    spiTransaction.txBuf = TransportTxBuf;
    spiTransaction.rxBuf = TransportRxBuf;
    
    // Check to see if transport is successful. If not, reset TxBufLen to allow
    // another write to be processed
    if( ! SPI_transfer(spiHandle, &spiTransaction) )
    {
      TransportTxBufLen = 0;
    }

    ICall_leaveCriticalSection(key);

    return TransportTxBufLen;
}
// -----------------------------------------------------------------------------
//! \brief      This routine initializes and begins a SPI transaction
//!
//! \param[in]  len - Number of bytes to write.
//!
//! \return     uint16_t - number of bytes written to transport
// -----------------------------------------------------------------------------
uint16_t NPITLSPI_writeTransport(uint16_t len)
{
    int16 i = 0;
    ICall_CSState key;
    
    key = ICall_enterCriticalSection();

    // Shift all bytes in TX Buffer up ZERO_PAD indexes. SPI Driver clips off 
    // first byte
    // NPI TL already shifts bytes up 1 index for SOF before calling write()
    for (i = len + 1; i > 0; i--)
    {
        npiTxBuf[i + ZERO_PAD] = npiTxBuf[i];
    }
    
    // Clear zero pad bytes
    memset(npiTxBuf, 0, ZERO_PAD);
    
    npiTxBuf[NPI_SPI_MSG_SOF_IDX + ZERO_PAD] = NPI_SPI_MSG_SOF;
    npiTxBuf[len + ZERO_PAD + 1] = NPITLSPI_calcFCS((uint8_t *)&npiTxBuf[2],len);
    tlWriteLen = len + ZERO_PAD + 2; // 2 = SOF + FCS 
    
    // Clear DMA Rx buffer and clear extra Tx buffer bytes to ensure clean buffer
    //    for next RX/TX
    memset(npiRxBuf, 0, npiBufSize);
    memset(&npiTxBuf[tlWriteLen], 0, npiBufSize - tlWriteLen);

    // set up the SPI Transaction
    spiTransaction.count = npiBufSize;
    spiTransaction.txBuf = npiTxBuf;
    spiTransaction.rxBuf = npiRxBuf;
    
    // Check to see if transport is successful. If not, reset TxBufLen to allow
    // another write to be processed
    if (!SPI_transfer(spiHandle, &spiTransaction))
    {
      tlWriteLen = 0;
    }

    ICall_leaveCriticalSection(key);

    return len;
}
// -----------------------------------------------------------------------------
//! \brief      This callback is invoked on transmission completion
//!
//! \param[in]  handle - handle to the SPI port
//! \param[in]  objTransaction    - handle for SPI transmission
//!
//! \return     void
// -----------------------------------------------------------------------------
static void NPITLSPI_CallBack(SPI_Handle handle, SPI_Transaction *objTransaction)
{
    uint16_t i;
    uint16_t readLen = 0;
    uint16_t storeWriteLen;
    
    // Check if a valid packet was found
    // SOF:
    if (npiRxBuf[NPI_SPI_MSG_SOF_IDX] == NPI_SPI_MSG_SOF &&
            objTransaction->count)
    {
        // Length:
        readLen = npiRxBuf[NPI_SPI_MSG_LEN_LSB_IDX];
        readLen += ((uint16)npiRxBuf[NPI_SPI_MSG_LEN_MSB_IDX] << 8);
        readLen += NPI_SPI_MSG_HDR_NOSOF_LEN; // Include the header w/o SOF
        
        // FCS:
        if (npiRxBuf[readLen + 1] == 
              NPITLSPI_calcFCS(&npiRxBuf[NPI_SPI_MSG_LEN_LSB_IDX],readLen))
        {
            // Message is valid. Shift bytes to remove SOF
            for (i = 0 ; i < readLen; i++)
            {
                npiRxBuf[i] = npiRxBuf[i + 1];
            }
        }
        else
        {
            // Invalid FCS. Discard message
            readLen = 0;
        }
    }
    
    //All bytes in TxBuf must be sent by this point
    storeWriteLen = tlWriteLen;
    tlWriteLen = 0; 
    RxActive = FALSE;  
    
    if (npiTransmitCB)
    {
        npiTransmitCB(readLen,storeWriteLen);
    }
}
// -----------------------------------------------------------------------------
//! \brief      This callback is invoked on transmission completion
//!
//! \param[in]  handle - handle to the SPI port
//! \param[in]  objTransaction    - handle for SPI transmission
//!
//! \return     void
// -----------------------------------------------------------------------------
static void NPITLSPI_CallBack(SPI_Handle handle, SPI_Transaction  *objTransaction)
{
    uint8 i;
    uint16 readLen = 0;
    uint16 storeTxLen = TransportTxBufLen;
    
    // Check if a valid packet was found
    // SOF:
    if ( TransportRxBuf[SPI_RX_SOF_INDEX] == SPI_SOF &&
            objTransaction->count)
    {
        // Length:
        readLen = TransportRxBuf[SPI_RX_LEN_INDEX];
        
        // FCS:
        if ( TransportRxBuf[readLen + SPI_RX_HDR_LEN] == 
                NPITLSPI_calcFCS(&TransportRxBuf[SPI_RX_LEN_INDEX],readLen + 1) )
        {
            // Message is valid. Shift bytes to remove header 
            for( i = 0 ; i < readLen ; i++)
            {
                TransportRxBuf[i] = TransportRxBuf[i + SPI_RX_HDR_LEN];
            }
        }
        else
        {
            // Invalid FCS. Discard message
            readLen = 0;
        }
    }
    
     //All bytes in TxBuf must be sent by this point
    TransportTxBufLen = 0;
    RxActive = FALSE;
    
    if ( npiTransmitCB )
    {
        npiTransmitCB(readLen,storeTxLen);
    }


}