// -----------------------------------------------------------------------------
//! \brief      This callback is invoked on Write completion
//!
//! \param[in]  handle - handle to the UART port
//! \param[in]  ptr    - pointer to data to be transmitted
//! \param[in]  size   - size of the data
//!
//! \return     void
// -----------------------------------------------------------------------------
static void NPITLUART_writeCallBack(UART_Handle handle, void *ptr, size_t size)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

#ifdef POWER_SAVING
    if ( !RxActive )
    {
        UART_readCancel(uartHandle);
        if ( npiTransmitCB )
        {
            npiTransmitCB(TransportRxLen,TransportTxLen);
        }
    }

    TxActive = FALSE;
    
#else
    if ( npiTransmitCB )
    {
        npiTransmitCB(0,TransportTxLen);
    }
#endif //POWER_SAVING

    ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine writes copies buffer addr to the transport layer.
//!
//! \param[in]  len - Number of bytes to write.
//!
//! \return     uint8 - number of bytes written to transport
// -----------------------------------------------------------------------------
uint16 NPITLUART_writeTransport(uint16 len)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();
    
    TransportTxLen = len;

#ifdef POWER_SAVING
    TxActive = TRUE;

    // Start reading prior to impending write transaction
    // We can only call UART_write() once MRDY has been signaled from Master
    // device
    NPITLUART_readTransport();
#else
    // Check to see if transport is successful. If not, reset TxLen to allow
    // another write to be processed
    if(UART_write(uartHandle, TransportTxBuf, TransportTxLen) == UART_ERROR )
    {
      TransportTxLen = 0;
    }
#endif //POWER_SAVING
    ICall_leaveCriticalSection(key);
    
    return TransportTxLen;
}
Esempio n. 3
0
// -----------------------------------------------------------------------------
//! \brief      This callback is invoked on Write completion
//!
//! \param[in]  handle - handle to the UART port
//! \param[in]  ptr    - pointer to data to be transmitted
//! \param[in]  size   - size of the data
//!
//! \return     void
// -----------------------------------------------------------------------------
static void SDITLUART_writeCallBack(UART_Handle handle, void *ptr, size_t size)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();
    uint8 errStatus = 0;

    if (errStatus = ((UARTCC26XX_Handle)handle->object)->status)
    {
      //report UART error status to application 
      if(incomingRXErrorStatusAppCBFunc != NULL)
        incomingRXErrorStatusAppCBFunc(UART_ERROR_EVT, &errStatus, sizeof(errStatus));
    }

#ifdef POWER_SAVING
    if ( !RxActive )
    {
        UART_readCancel(uartHandle);
        if ( sdiTransmitCB )
        {
            sdiTransmitCB(TransportRxLen,TransportTxLen);
        }
    }

    TxActive = FALSE;
    
#else
    if ( sdiTransmitCB )
    {
        sdiTransmitCB(0,TransportTxLen);
    }
#endif //POWER_SAVING

    ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine initializes the transport layer and opens the port
//!             of the device. Note that based on project defines, either the
//!             UART, or SPI driver can be used.
//!
//! \param[in]  npiCBTx - Call back function for TX complete event
//! \param[in]  npiCBRx - Call back function for RX event
//! \param[in]  npiCBMrdy - Call back function for MRDY event
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITL_initTL(npiRtosCB_t npiCBTx, npiRtosCB_t npiCBRx, npiRtosCB_t npiCBMrdy)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    taskTxCB = npiCBTx;
    taskRxCB = npiCBRx;
#if (NPI_FLOW_CTRL == 1)
    taskMrdyCB = npiCBMrdy;
#endif // NPI_FLOW_CTRL = 1

    transportInit(npiRxBuf,npiTxBuf, NPITL_transmissionCallBack);

#if (NPI_FLOW_CTRL == 1)
    SRDY_DISABLE();

    // Initialize SRDY/MRDY. Enable int after callback registered
    hNpiHandshakePins = PIN_open(&npiHandshakePins, npiHandshakePinsCfg);
    PIN_registerIntCb(hNpiHandshakePins, NPITL_MRDYPinHwiFxn);
    PIN_setConfig(hNpiHandshakePins, PIN_BM_IRQ, MRDY_PIN | PIN_IRQ_BOTHEDGES);

    // Enable wakeup
    PIN_setConfig(hNpiHandshakePins, PINCC26XX_BM_WAKEUP, MRDY_PIN | PINCC26XX_WAKEUP_NEGEDGE);

    mrdy_state = PIN_getInputValue(MRDY_PIN);
#endif // NPI_FLOW_CTRL = 1

    ICall_leaveCriticalSection(key);

    return;
}
Esempio n. 5
0
uint8 SDITLUART_configureUARTParams(UART_Params *initParams)
{ 
  uint8 status = SUCCESS;
  ICall_CSState key;
  
  SDITLUART_closeUART();
  
  key = ICall_enterCriticalSection();
  
  // Open / power on the UART.
  uartHandle = UART_open(Board_UART, &paramsUART);
  if(uartHandle != NULL)
  {
    //DEBUG("UART_open successful");
  }else{
    //DEBUG("ERROR in UART_open");
    status = FAILURE;
  }
 
  //Enable Partial Reads on all subsequent UART_read()
  status = UART_control(uartHandle, UARTCC26XX_RETURN_PARTIAL_ENABLE,  NULL);
  
  ICall_leaveCriticalSection(key);
  
  #ifndef POWER_SAVING
    //Initiate first read to start polling UART
    SDITLUART_readTransport();
  #endif //POWER_SAVING
  
  return status;
}
Esempio n. 6
0
// -----------------------------------------------------------------------------
//! \brief      This callback is invoked on Read completion of readSize/receive
//!             timeout
//!
//! \param[in]  handle - handle to the UART port
//! \param[in]  ptr    - pointer to buffer to read data into
//! \param[in]  size   - size of the data
//!
//! \return     void
// -----------------------------------------------------------------------------
static void SDITLUART_readCallBack(UART_Handle handle, void *ptr, size_t size)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();
    uint8 errStatus = 0;

    if (errStatus = ((UARTCC26XX_Handle)handle->object)->status)
    {
      //report UART error status to application 
      if(incomingRXErrorStatusAppCBFunc != NULL)
        incomingRXErrorStatusAppCBFunc(UART_ERROR_EVT, &errStatus, sizeof(errStatus));
    }

    if (size)
    {
        if (size != SDITLUART_readIsrBuf(size))
        {
            // Buffer overflow imminent. Cancel read and pass to higher layers
            // for handling
#ifdef POWER_SAVING
            RxActive = FALSE;
#endif //POWER_SAVING
            if ( sdiTransmitCB )
            {
                sdiTransmitCB(SDI_TL_BUF_SIZE,TransportTxLen);
            }
        }
    }

#ifdef POWER_SAVING
    // Read has been cancelled by transport layer, or bus timeout and no bytes in FIFO
    //    - do not invoke another read
    if ( !UARTCharsAvail(((UARTCC26XX_HWAttrs const *)(uartHandle->hwAttrs))->baseAddr) &&
            mrdy_flag )
    {
        RxActive = FALSE;
        
        // If TX has also completed then we are safe to issue call back
        if ( !TxActive && sdiTransmitCB )
        {
            sdiTransmitCB(TransportRxLen,TransportTxLen);
        }
    }
    else
    {
        UART_read(uartHandle, &isrRxBuf[0], UART_ISR_BUF_SIZE);
    }
#else
    if ( sdiTransmitCB )
    {
        sdiTransmitCB(size,0);
    }
    TransportRxLen = 0;
    UART_read(uartHandle, &isrRxBuf[0], UART_ISR_BUF_SIZE);
#endif //POWER_SAVING

    ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine writes data from the buffer to the transport layer.
//!
//! \param[in]  buf - Pointer to buffer to write data from.
//! \param[in]  len - Number of bytes to write.
//!
//! \return     uint16 - the number of bytes written to transport
// -----------------------------------------------------------------------------
uint16 NPITL_writeTL(uint8 *buf, uint16 len)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    // Writes are atomic at transport layer
    if ( NPITL_checkNpiBusy() )
    {
        ICall_leaveCriticalSection(key);
        return 0;
    }

    // If len of message is greater than fragment size
    // then message must be sent over the span of multiple
    // fragments
    if ( len > NPI_MAX_FRAG_SIZE )
    {
      msgFrag = buf + NPI_MAX_FRAG_SIZE;
      msgFragLen = len - NPI_MAX_FRAG_SIZE;
      len = NPI_MAX_FRAG_SIZE;
    }
    else
    {
      msgFrag = NULL;
      msgFragLen = 0;
    }

    memcpy(npiTxBuf, buf, len);
    npiTxBufLen = len;
    npiTxActive = TRUE;
    txPktCount++;

    len = transportWrite(npiTxBufLen);

#if (NPI_FLOW_CTRL == 1)
    SRDY_ENABLE();
#endif // NPI_FLOW_CTRL = 1

    ICall_leaveCriticalSection(key);

    return len;
}
// -----------------------------------------------------------------------------
//! \brief      This routine reads data from the UART
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_readTransport(void)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();
    
#ifdef POWER_SAVING
    RxActive = TRUE;
#endif //POWER_SAVING

    TransportRxLen = 0;
    UART_read(uartHandle, &isrRxBuf[0], UART_ISR_BUF_SIZE);
    
    ICall_leaveCriticalSection(key);
}
Esempio n. 9
0
void SDITLUART_closeUART(void)
{
  ICall_CSState key;
  
  key = ICall_enterCriticalSection();
  
  // Cancel any pending reads
  UART_readCancel(uartHandle);
  
  // Close / power off the UART.
  UART_close(uartHandle);
  
  ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine reads data from the UART
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_readTransport(void)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

#if (NPI_FLOW_CTRL == 1)
    RxActive = TRUE;
#endif // NPI_FLOW_CTRL = 1

    TransportRxLen = 0;
    UART_read(uartHandle, &isrRxBuf[0], UART_ISR_BUF_SIZE);

    ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \brief      This callback is invoked on Read completion of readSize/receive
//!             timeout
//!
//! \param[in]  handle - handle to the UART port
//! \param[in]  ptr    - pointer to buffer to read data into
//! \param[in]  size   - size of the data
//!
//! \return     void
// -----------------------------------------------------------------------------
static void NPITLUART_readCallBack(UART_Handle handle, void *ptr, size_t size)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    if (size)
    {
        if (size != NPITLUART_readIsrBuf(size))
        {
            // Buffer overflow imminent. Cancel read and pass to higher layers
            // for handling
#ifdef POWER_SAVING
            RxActive = FALSE;
#endif //POWER_SAVING
            if ( npiTransmitCB )
            {
                npiTransmitCB(NPI_TL_BUF_SIZE,TransportTxLen);
            }
        }
    }

#ifdef POWER_SAVING
    // Read has been cancelled by transport layer, or bus timeout and no bytes in FIFO
    //    - do not invoke another read
    if ( !UARTCharsAvail(((UARTCC26XX_HWAttrs const *)(uartHandle->hwAttrs))->baseAddr) &&
            mrdy_flag )
    {
        RxActive = FALSE;
        
        // If TX has also completed then we are safe to issue call back
        if ( !TxActive && npiTransmitCB )
        {
            npiTransmitCB(TransportRxLen,TransportTxLen);
        }
    }
    else
    {
        UART_read(uartHandle, &isrRxBuf[0], UART_ISR_BUF_SIZE);
    }
#else
    if ( npiTransmitCB )
    {
        npiTransmitCB(size,0);
    }
    TransportRxLen = 0;
    UART_read(uartHandle, &isrRxBuf[0], UART_ISR_BUF_SIZE);
#endif //POWER_SAVING

    ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine is used to handle an MRDY transition from a task
//!             context. Certain operations such as UART_read() cannot be
//!             performed from a HWI context
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITL_handleMrdyEvent(void)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    // Check to make sure this event is not occurring during the next packet
    // transmission
    if ( PIN_getInputValue(MRDY_PIN) == 0 ||
        (npiTxActive && mrdyPktStamp == txPktCount ) )
    {
        transportMrdyEvent();
        SRDY_ENABLE();
    }

    ICall_leaveCriticalSection(key);
}
Esempio n. 13
0
// -----------------------------------------------------------------------------
//! \brief      This routine is called from the application context when REM RDY
//!             is de-asserted
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLSPI_handleRemRdyEvent(void)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    // If write has not be set up then a read must occur during this
    // transaction. There is a possibility that after bidirectional 
    // transaction there is an extra MRDY event. This event 
    // could cause a double read (which would clear the RX Buffer) so this 
    // check ignores the MRDY event if Rx is already in progress
    if (!tlWriteLen && !RxActive)
    {
      NPITLSPI_readTransport();
    }

    ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \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 is called from the application context when MRDY is
//!             de-asserted
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLSPI_handleMrdyEvent()
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    // If we have not already set up a write then we must be reading
    // during this transaction. There is a possibility that after
    // bidirectional transaction there is an extra MRDY event. This event 
    // could cause a double read (which would clear the RX Buffer) so this 
    // check ignores the MRDY event if Rx is already in progress
    if (!TransportTxBufLen && !RxActive)
    {
      NPITLSPI_readTransport();
    }

    ICall_leaveCriticalSection(key);
    return;
}
Esempio n. 16
0
// -----------------------------------------------------------------------------
//! \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 routine stops any pending reads
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_stopTransfer(void)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    mrdy_flag = 1;

    // If we have no bytes in FIFO yet we must assume there was nothing to read
    // or that the FIFO has already been read for this UART_read()
    // In either case UART_readCancel will call the read CB function and it will
    // invoke npiTransmitCB with the appropriate number of bytes read
    if (!UARTCharsAvail(((UARTCC26XX_HWAttrs const *)(uartHandle->hwAttrs))->baseAddr))
    {
        RxActive = FALSE;
        UART_readCancel(uartHandle);
    }

    ICall_leaveCriticalSection(key);
    return;
}
Esempio n. 18
0
// -----------------------------------------------------------------------------
//! \brief      This routine reads data from the transport layer
//!             and places it into the buffer.
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLSPI_readTransport(void)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    tlWriteLen = 0;
    RxActive = TRUE;

    // 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.txBuf = npiTxBuf;
    spiTransaction.rxBuf = npiRxBuf;
    spiTransaction.count = npiBufSize;
    SPI_transfer(spiHandle, &spiTransaction);

    ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine reads data from the transport layer
//!             and places it into the buffer.
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLSPI_readTransport()
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();

    RxActive = TRUE;
    TransportTxBufLen = 0;

    // 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.txBuf = TransportTxBuf;
    spiTransaction.rxBuf = TransportRxBuf;
    spiTransaction.count = NPI_TL_BUF_SIZE;
    SPI_transfer(spiHandle, &spiTransaction);

    ICall_leaveCriticalSection(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine is called from the application context when MRDY is
//!             de-asserted
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_handleMrdyEvent(void)
{
    ICall_CSState key;
    key = ICall_enterCriticalSection();
    
    mrdy_flag = 0;

    // If we haven't already begun reading, now is the time before Master
    //    potentially starts to send data
    // The !TxActive condition is because we will call UART_npiRead() prior to setting
    // TxActive true. There is the possibility that MRDY gets set high which
    // clears RxActive prior to us getting to this event. This will cause us to
    // read twice per transaction which will cause the transaction to never
    // complete
    if ( !RxActive && !TxActive )
    {
        NPITLUART_readTransport();
    }

    // If we have something to write, then the Master has signalled it is ready
    //    to receive. Time to write.
    if ( TxActive )
    {
        // Check to see if transport is successful. If not, reset TxLen to allow
        // another write to be processed
        if ( UART_write(uartHandle, TransportTxBuf, TransportTxLen) == UART_ERROR )
        {
          TxActive = FALSE;
          TransportTxLen = 0;
        }
    }

    ICall_leaveCriticalSection(key);
    
    return;
}