示例#1
0
// -----------------------------------------------------------------------------
//! \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_t - NPI error code value
// -----------------------------------------------------------------------------
uint8_t NPITL_writeTL(uint8_t *buf, uint16_t len)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS(); 
    // Check to make sure NPI is not currently in a transaction
    if (TL_ready != NPITL_getTlStatus())
    {
        NPIUtil_ExitCS(key);
        return NPI_BUSY;
    }
    
    // Check to make sure that write size is not greater than what is 
    // allowed
    if (len > npiBufSize)
    {
        NPIUtil_ExitCS(key);
        return NPI_TX_MSG_OVERSIZE;
    }
    // Copy into the second byte of npiTxBuf. This will save Serial Port
    // Specific TL code from having to shift one byte later on for SOF.
    //memset(npiTxBuf, 0, npiTLParams.npiTLBufSize);
    memcpy(&npiTxBuf[1], buf, len);
    npiTxBufLen = len;
    npiTxActive = TRUE;
    txPktCount++;
    trasnportLayerState = TL_busy;
    transportWrite(npiTxBufLen);
    NPIUtil_ExitCS(key);
    return NPI_SUCCESS;
}
示例#2
0
// -----------------------------------------------------------------------------
//! \brief      This routine writes copies buffer addr to the transport layer.
//!
//! \param[in]  len - Number of bytes to write.
//!
//! \return     uint16_t - number of bytes written to transport
// -----------------------------------------------------------------------------
uint16_t NPITLUART_writeTransport(uint16_t len)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();

    npiTxBuf[NPI_UART_MSG_SOF_IDX] = NPI_UART_MSG_SOF;
    npiTxBuf[len + 1] = NPITLUART_calcFCS((uint8_t *)&npiTxBuf[1],len);
    TransportTxLen = len + 2;

#ifdef POWER_SAVING
    TxActive = TRUE;

    // Start reading prior to impending write transaction
    // We can only call UART_write() once REM RDY 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, npiTxBuf, TransportTxLen) == UART_ERROR)
    {
        TransportTxLen = NPI_BUSY;
    }
#endif //POWER_SAVING

    NPIUtil_ExitCS(key);

    return len;
}
示例#3
0
// -----------------------------------------------------------------------------
//! \brief      This routine is called from the application context when REM RDY
//!             is de-asserted
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_handleRemRdyEvent(void)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();

    remRdy_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 REM RDY 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, npiTxBuf, TransportTxLen) == UART_ERROR)
        {
            TxActive = FALSE;
            TransportTxLen = 0;
        }
    }

    NPIUtil_ExitCS(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine closes the transport layer
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITL_closeTL(void)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();
    
    // Clear NPI Task Call backs
    memset(&taskCBs, 0, sizeof(taskCBs));
  
    // Free Transport Layer RX/TX buffers
    npiBufSize = 0;
    NPIUTIL_FREE(npiRxBuf);
    NPIUTIL_FREE(npiTxBuf);
  
    // Close Transport Layer 
    transportClose();
    
#if (NPI_FLOW_CTRL == 1)
    // Clear mrdy and srdy PIN IDs
    remRdyPIN = (IOID_UNUSED & IOC_IOID_MASK); // Set to 0x000000FF
    locRdyPIN = (IOID_UNUSED & IOC_IOID_MASK); // Set to 0x000000FF
    
    // Clear PIN IDs from PIN Configuration
    npiHandshakePinsCfg[REM_RDY_PIN_IDX] &= ~remRdyPIN; 
    npiHandshakePinsCfg[LOC_RDY_PIN_IDX] &= ~locRdyPIN;
    
    // Close PIN Handle
    PIN_close(hNpiHandshakePins);
    
    // Release Power Management
    NPITL_relPM();
#endif // NPI_FLOW_CTRL = 1

    NPIUtil_ExitCS(key);
}
示例#5
0
// -----------------------------------------------------------------------------
//! \brief      This routine closes the transport layer
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITL_closeTL(void)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();
    
    // Clear NPI Task Call backs
    memset(&taskCBs, 0, sizeof(taskCBs));
  
    // Free Transport Layer RX/TX buffers
    npiBufSize = 0;
    NPIUTIL_FREE(npiRxBuf);
    NPIUTIL_FREE(npiTxBuf);
  
    // Close Transport Layer 
    transportClose();
    
#ifdef POWER_SAVING  
    // Close PIN Handle
    PIN_close(hNpiHandshakePins);
#ifdef NPI_SW_HANDSHAKING_DEBUG
    PIN_close(hNpiProfilingDebugPin);
#endif //NPI_SW_HANDSHAKING
    // Release Power Management
    NPITL_relPM();
#endif //POWER_SAVING

    NPIUtil_ExitCS(key);
}
示例#6
0
// -----------------------------------------------------------------------------
//! \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_handleRemRdyEvent(void)
{
	_npiCSKey_t key;
	key = NPIUtil_EnterCS();
	//If the UART port is closed, then open it
    if(HS_GPIO_STATE & handshakingState)
    {
    	NPITL_setPM();
    	//Close the GPIO, then
    	//Open the UART
    	 PIN_close(hNpiHandshakePins);
    	 transportOpen(npiTLParams.portBoardID,
					  &npiTLParams.portParams.uartParams,
					  NPITL_transmissionCallBack, NPITL_chirpRecievedCB);
    	 handshakingState |=  HS_WAITFORCHIRP|HS_UART_STATE;
    	 //Clear GPIO flag, we are no longer in this state
    	 handshakingState &= ~HS_GPIO_STATE;
    }
    else
    {
    	//Once UART is open
        //Handle the RemRdy Event
        transportRemRdyEvent();
    }
    NPIUtil_ExitCS(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine is called from the application context when REM RDY
//!             is de-asserted
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_handleRemRdyEvent(void)
{
  _npiCSKey_t key;
  key = NPIUtil_EnterCS();

  // If read has not yet been started, now is the time before Master
  // potentially starts to send data
  // 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 write has already been initialized then kick off the driver write
  // now that Master has signalled it is ready
  if (TxActive)
  {
    // Check to see if transport is successful. If not, reset TxLen to allow
    // another write to be processed
    if (UART_write(uartHandle, npiTxBuf, TransportTxLen) == UART_ERROR)
    {
      TxActive = FALSE;
      TransportTxLen = 0;
    }
  }

  NPIUtil_ExitCS(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_t - NPI error code value
// -----------------------------------------------------------------------------
uint8_t NPITL_writeTL(uint8_t *buf, uint16_t len)
{
#if (NPI_FLOW_CTRL == 1)
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();
#endif // NPI_FLOW_CTRL = 1
    
    // Check to make sure NPI is not currently in a transaction
    if (NPITL_checkNpiBusy())
    {
#if (NPI_FLOW_CTRL == 1)
        NPIUtil_ExitCS(key);
#endif // NPI_FLOW_CTRL = 1

        return NPI_BUSY;
    }
    
    // Check to make sure that write size is not greater than what is 
    // allowed
    if (len > npiBufSize)
    {
#if (NPI_FLOW_CTRL == 1)
        NPIUtil_ExitCS(key);
#endif // NPI_FLOW_CTRL = 1

        return NPI_TX_MSG_OVERSIZE;
    }
    
    // Copy into the second byte of npiTxBuf. This will save Serial Port
    // Specific TL code from having to shift one byte later on for SOF. 
    memcpy(&npiTxBuf[1], buf, len);
    npiTxBufLen = len;
    npiTxActive = TRUE;
    txPktCount++;

    transportWrite(npiTxBufLen);

#if (NPI_FLOW_CTRL == 1)
    LocRDY_ENABLE();
    NPIUtil_ExitCS(key);
#endif // NPI_FLOW_CTRL = 1

    return NPI_SUCCESS;
}
示例#9
0
// -----------------------------------------------------------------------------
//! \brief      This routine reads data from the UART
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_readTransport(void)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();

#ifdef POWER_SAVING
    RxActive = TRUE;
#endif //POWER_SAVING

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

    NPIUtil_ExitCS(key);
}
// -----------------------------------------------------------------------------
//! \brief      This routine reads data from the UART
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_readTransport(void)
{
  _npiCSKey_t key;
  key = NPIUtil_EnterCS();
  
#if (NPI_FLOW_CTRL == 1)
  RxActive = TRUE;
#endif // NPI_FLOW_CTRL = 1

  TransportRxLen = 0;
  
  // UART driver will automatically reject this read if already in use
  UART_read(uartHandle, npiRxBuf, NPI_UART_MSG_SOF_LEN);
  
  NPIUtil_ExitCS(key);
}
示例#11
0
// -----------------------------------------------------------------------------
//! \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]  params - Transport Layer parameters
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITL_openTL(NPITL_Params *params)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();
    
    // Set NPI Task Call backs
    memcpy(&taskCBs, &params->npiCallBacks, sizeof(params->npiCallBacks));
    
    // Allocate memory for Transport Layer Tx/Rx buffers
    npiBufSize = params->npiTLBufSize;
    npiRxBuf = NPIUTIL_MALLOC(params->npiTLBufSize);
    memset(npiRxBuf, 0, npiBufSize);
    npiTxBuf = NPIUTIL_MALLOC(params->npiTLBufSize);
    memset(npiTxBuf, 0, npiBufSize);

    // This will be updated to be able to select SPI/UART TL at runtime
    // Now only compile time with the NPI_USE_[UART,SPI] flag

#if defined(NPI_USE_UART)
#elif defined(NPI_USE_SPI)
    transportOpen(params->portBoardID, 
                  &params->portParams.spiParams, 
                  NPITL_transmissionCallBack);
#endif //NPI_USE_UART
    
	hNpiHandshakePins = PIN_open(&npiHandshakePins, npiHandshakePinsCfg);
	PIN_registerIntCb(hNpiHandshakePins, NPITL_remRdyPINHwiFxn);
	PIN_setConfig(hNpiHandshakePins,
				  PIN_BM_IRQ,
				  Board_UART_RX | PIN_IRQ_BOTHEDGES);

	// Enable wakeup
	PIN_setConfig(hNpiHandshakePins,
				  PINCC26XX_BM_WAKEUP,
				  Board_UART_RX | PINCC26XX_WAKEUP_NEGEDGE);
#ifdef NPI_SW_HANDSHAKING_DEBUG
	hNpiProfilingDebugPin= PIN_open(&npiProfilingDebugPin, npiProfilingDebugPinCfg);
#endif //NPI_SW_HANDSHAKING_DEBUG

	npiTLParams = *params;	//Keep a copy of TLParams local to the TL so that the UART can be closed/reopened
#ifndef POWER_SAVING
    // This call will start repeated Uart Reads when Power Savings is disabled
    transportRead();
#endif 

    NPIUtil_ExitCS(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_handleRemRdyEvent(void)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();
  
    // Check to make sure this event is not occurring during the next packet
    // transmission
    if (PIN_getInputValue(remRdyPIN) == 0 || 
        (npiTxActive && mrdyPktStamp == txPktCount))
    {
        transportRemRdyEvent();
        npiRxActive = TRUE;
        LocRDY_ENABLE();
    }
    
    NPIUtil_ExitCS(key);
}
// -----------------------------------------------------------------------------
//! \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
// -----------------------------------------------------------------------------
void NPITLUART_writeCallBack(UART_Handle handle, void *ptr, size_t size)
{
  _npiCSKey_t key;
  key = NPIUtil_EnterCS();

#if (NPI_FLOW_CTRL == 1)
  // This is a CC26xx/CC13xx Driverlib specific call (not optimal...)
  // This is necessary because the write call back needs to know if any bytes 
  // have been received from the peer device. If no bytes have been received
  // the transaction can be ended. However, If a simultaneous read/write occurs
  // within the same transaction then simple checking if RxActive or even the
  // state variable of the read call back is not enough. In testing the UART 
  // read call back was never invoked prior to the write call back so we must
  // bypass the driver and directly check if there are bytes in the RX FIFO
  if ( !UARTCharsAvail(((UARTCC26XX_HWAttrsV1 const *)(handle->hwAttrs))->baseAddr) )
  {
    UART_readCancel(uartHandle);
    RxActive = FALSE;

    if (npiTransmitCB)
    {
      if (NPITLUART_validPacketFound() == NPI_SUCCESS)
      {
        // Decrement as to not include trailing FCS byte
        TransportRxLen--;
      }
      else
      {
        // Did not receive valid packet so denote RX length as zero in CB
        TransportRxLen = 0;
      }

      npiTransmitCB(TransportRxLen,TransportTxLen);
    }
  }

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

  NPIUtil_ExitCS(key);
}
示例#14
0
// -----------------------------------------------------------------------------
//! \brief      This routine stops any pending reads
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITLUART_stopTransfer(void)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();

    remRdy_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);
    }

    NPIUtil_ExitCS(key);
}
示例#15
0
// -----------------------------------------------------------------------------
//! \brief      This callback is invoked on the completion of one transmission
//!             to/from the host MCU. Any bytes receives will be [0,Rxlen) in
//!             npiRxBuf.
//!             If bytes were receives or transmitted, this function notifies
//!             the NPI task via registered call backs
//!
//! \param[in]  Rxlen   - length of the data received
//! \param[in]  Txlen   - length of the data transferred
//!
//! \return     void
// -----------------------------------------------------------------------------
static void NPITL_transmissionCallBack(uint16_t Rxlen, uint16_t Txlen)
{
    npiRxBufHead = 0;
    npiRxBufTail = Rxlen;
    npiTxActive = FALSE;
    
    // If Task is registered, invoke transaction complete callback
    if (taskCBs.transCompleteCB)
    {
        taskCBs.transCompleteCB(Rxlen, Txlen);
    }
#ifdef NPI_SW_HANDSHAKING_DEBUG
    //Set the profiling pin high
    PIN_setOutputValue(hNpiProfilingDebugPin, profilingDebugPin, 1);
#endif //NPI_SW_HANDSHAKING_DEBUG
    // Close the UART
    transportClose();
    // Open the Pins for ISR
    hNpiHandshakePins = PIN_open(&npiHandshakePins, npiHandshakePinsCfg);
    	//replace remRdyPIN with Board_UART_RX
    	PIN_registerIntCb(hNpiHandshakePins, NPITL_remRdyPINHwiFxn);
    	PIN_setConfig(hNpiHandshakePins,
    				  PIN_BM_IRQ,
    				  Board_UART_RX | PIN_IRQ_BOTHEDGES);

    	// Enable wakeup
    	PIN_setConfig(hNpiHandshakePins,
    				  PINCC26XX_BM_WAKEUP,
    				  Board_UART_RX | PINCC26XX_WAKEUP_NEGEDGE);
#ifdef NPI_SW_HANDSHAKING_DEBUG
    	//Indicate that we are now asleep in the GPIO state
    	PIN_setOutputValue(hNpiProfilingDebugPin, profilingDebugPin, 0);
#endif //NPI_SW_HANDSHAKING_DEBUG
    	//It is also valid to clear all flags at this point
    	_npiCSKey_t key;
    	key = NPIUtil_EnterCS();
    	handshakingState = HS_GPIO_STATE;
    	NPIUtil_ExitCS(key);
#ifdef POWER_SAVING
    NPITL_relPM();
#endif //POWER_SAVING
}
示例#16
0
// -----------------------------------------------------------------------------
//! \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]  params - Transport Layer parameters
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITL_openTL(NPITL_Params *params)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();
    
    // Set NPI Task Call backs
    memcpy(&taskCBs, &params->npiCallBacks, sizeof(params->npiCallBacks));
    
    // Allocate memory for Transport Layer Tx/Rx buffers
    npiBufSize = params->npiTLBufSize;
    npiRxBuf = NPIUTIL_MALLOC(params->npiTLBufSize);
    memset(npiRxBuf, 0, npiBufSize);
    npiTxBuf = NPIUTIL_MALLOC(params->npiTLBufSize);
    memset(npiTxBuf, 0, npiBufSize);
    
    
    hNpiUartRxPin = PIN_open(&npiUartRxPin, npiUartRxPinCfg);
    PIN_registerIntCb(hNpiUartRxPin, NPITL_rxPinHwiFxn);
    PIN_setConfig(hNpiUartRxPin, 
                  PIN_BM_IRQ, 
                  Board_UART_RX | PIN_IRQ_BOTHEDGES);

    // Enable wakeup
    PIN_setConfig(hNpiUartRxPin, 
                  PINCC26XX_BM_WAKEUP, 
                  Board_UART_RX | PINCC26XX_WAKEUP_NEGEDGE);
    //Note that open TL is only called when NPI task is being initialized
    //transportLayerState variable defaults to closed.
#ifdef SWHS_DEBUG  
    //Open Profiling Pin if in debug mode 
    hNpiProfilingPin = PIN_open(&npiProfilingPin, npiProfilingPinCfg);
#endif //SWHS_DEBUG
    //Keep a copy of TLParams local to the TL so that the UART can be closed/reopened
    npiTLParams = *params;
    //Here we will initialize the transport which will setup the callbacks
    //This call does not open the UART
    transportInit( &npiTLParams.portParams.uartParams, 
                   NPITL_transmissionCallBack,
                   NPITL_handshakeCompleteCallBack);
    
    NPIUtil_ExitCS(key);
}
示例#17
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
// -----------------------------------------------------------------------------
void NPITLUART_writeCallBack(UART_Handle handle, void *ptr, size_t size)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();

#ifdef POWER_SAVING
    if (!RxActive)
    {
        UART_readCancel(uartHandle);

        if (npiTransmitCB)
        {
            if (NPITLUART_validPacketFound() == NPI_SUCCESS)
            {
                // Decrement as to not include trailing FCS byte
                TransportRxLen--;
            }
            else
            {
                // Did not receive valid packet so denote RX length as zero in CB
                TransportRxLen = 0;
            }

            npiTransmitCB(TransportRxLen,TransportTxLen);
        }
    }

    TxActive = FALSE;

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

    NPIUtil_ExitCS(key);
}
示例#18
0
// -----------------------------------------------------------------------------
//! \brief      This routine closes the transport layer
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITL_closeTL(void)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();
    
    // Clear NPI Task Call backs
    memset(&taskCBs, 0, sizeof(taskCBs));
  
    // Free Transport Layer RX/TX buffers
    npiBufSize = 0;
    NPIUTIL_FREE(npiRxBuf);
    NPIUTIL_FREE(npiTxBuf);
  
    // Close the RxPin
    PIN_close(hNpiUartRxPin);
    // Close UART transport Layer 
    transportClose();
    trasnportLayerState = TL_closed;
    
    NPITL_relPM();

    NPIUtil_ExitCS(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
// -----------------------------------------------------------------------------
void NPITLUART_readCallBack(UART_Handle handle, void *ptr, size_t size)
{
  static uint16_t payloadLen = 0;
  _npiCSKey_t key;
  key = NPIUtil_EnterCS();

  switch (readState)
  {
    case NPITLUART_READ_SOF:
      // Should only have read one byte in this state. 
      if (size == NPI_UART_MSG_SOF_LEN && npiRxBuf[0] == NPI_UART_MSG_SOF)
      {
        // Recevied SOF, Read HDR next. Do not save SOF byte
        UART_read(uartHandle, npiRxBuf, NPI_UART_MSG_HDR_LEN);
        readState = NPITLUART_READ_HDR;
      }
      break;
    
    case NPITLUART_READ_HDR:
      if (size == NPI_UART_MSG_HDR_LEN)
      {
        // Header has been read. Increment RxLen
        TransportRxLen += size;
        
        // Determine length of remainder of packet, add an extra byte for FCS
        payloadLen = BUILD_UINT16(npiRxBuf[0],npiRxBuf[1]) + 1;
        
        // Check to see if payload can fit in the remainder of the RxBuf
        if (payloadLen <= npiBufSize - TransportRxLen)
        {
          // Read remainder of packet
          UART_read(uartHandle, &npiRxBuf[TransportRxLen], payloadLen);
          readState = NPITLUART_READ_PLD;
        }
        else
        {
          // Read remainder of packet bytes but ignore them
          UART_read(uartHandle, npiRxBuf, npiBufSize);
          readState = NPITLUART_IGNORE;
        }
      }
      else
      {
        // Error has occured. Reset read state
        readState = NPITLUART_READ_SOF;
      }
    break;
    
    case NPITLUART_READ_PLD:
      if (payloadLen == size)
      {
        // All bytes are read
        TransportRxLen += size;
        
        // Check if FCS is valid
        if (NPITLUART_validPacketFound() == NPI_SUCCESS)
        {
          // Valid Packet. Decrement RxLen to not include FCS since it is
          // checked and valid
          TransportRxLen--;
          
#if (NPI_FLOW_CTRL == 1)
          RxActive = FALSE;
          
          // If TX has also completed then we are safe to issue call back
          if (!TxActive && npiTransmitCB)
          {
            npiTransmitCB(TransportRxLen,TransportTxLen);
          }
#else
          if (npiTransmitCB) 
          {
            npiTransmitCB(TransportRxLen,0);
          }
#endif // NPI_FLOW_CTRL = 1
        }
      }

      // Reset State. Full packet has been read or error has occurred
      readState = NPITLUART_READ_SOF;
      break;
    
    case NPITLUART_IGNORE:
      if (payloadLen == size)
      {
        // All bytes of oversized payload have been read. Reset state
        readState = NPITLUART_READ_SOF;
      }
      else
      {
        // Bytes remaining to be read
        payloadLen -= size;
        
        if (payloadLen > npiBufSize)
        {
          UART_read(uartHandle, npiRxBuf, npiBufSize);
        }
        else
        {
          UART_read(uartHandle, npiRxBuf, payloadLen);
        }
      }
      break;
    
    default:
      // Should not get here. If so reset read state
      readState = NPITLUART_READ_SOF;
      break;
  }

#if (NPI_FLOW_CTRL == 0)
  // Initiate next read of SOF byte
  if (readState == NPITLUART_READ_SOF)
  {
    TransportRxLen = 0;
    UART_read(uartHandle, npiRxBuf, NPI_UART_MSG_SOF_LEN);
  }
#endif // NPI_FLOW_CTRL = 0
  
  NPIUtil_ExitCS(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]  params - Transport Layer parameters
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPITL_openTL(NPITL_Params *params)
{
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();
    
    // Set NPI Task Call backs
    memcpy(&taskCBs, &params->npiCallBacks, sizeof(params->npiCallBacks));
    
    // Allocate memory for Transport Layer Tx/Rx buffers
    npiBufSize = params->npiTLBufSize;
    npiRxBuf = NPIUTIL_MALLOC(params->npiTLBufSize);
    memset(npiRxBuf, 0, npiBufSize);
    npiTxBuf = NPIUTIL_MALLOC(params->npiTLBufSize);
    memset(npiTxBuf, 0, npiBufSize);

    // This will be updated to be able to select SPI/UART TL at runtime
    // Now only compile time with the NPI_USE_[UART,SPI] flag
#if defined(NPI_USE_UART)
    transportOpen(params->portBoardID, 
                  &params->portParams.uartParams, 
                  NPITL_transmissionCallBack);
#elif defined(NPI_USE_SPI)
    transportOpen(params->portBoardID, 
                  &params->portParams.spiParams, 
                  NPITL_transmissionCallBack);
#endif //NPI_USE_UART
    
#if (NPI_FLOW_CTRL == 1)
    // Assign PIN IDs to remRdy and locRrdy
#ifdef NPI_MASTER
    remRdyPIN = (params->srdyPinID & IOC_IOID_MASK);
    locRdyPIN = (params->mrdyPinID & IOC_IOID_MASK);
#else
    remRdyPIN = (params->mrdyPinID & IOC_IOID_MASK);
    locRdyPIN = (params->srdyPinID & IOC_IOID_MASK);
#endif //NPI_MASTER
    
    // Add PIN IDs to PIN Configuration
    npiHandshakePinsCfg[REM_RDY_PIN_IDX] |= remRdyPIN;
    npiHandshakePinsCfg[LOC_RDY_PIN_IDX] |= locRdyPIN;
    
    // Initialize LOCRDY/REMRDY. Enable int after callback registered
    hNpiHandshakePins = PIN_open(&npiHandshakePins, npiHandshakePinsCfg);
    PIN_registerIntCb(hNpiHandshakePins, NPITL_remRdyPINHwiFxn);
    PIN_setConfig(hNpiHandshakePins, 
                  PIN_BM_IRQ, 
                  remRdyPIN | PIN_IRQ_BOTHEDGES);

    // Enable wakeup
    PIN_setConfig(hNpiHandshakePins, 
                  PINCC26XX_BM_WAKEUP, 
                  remRdyPIN | PINCC26XX_WAKEUP_NEGEDGE);
    
    remRdy_state = PIN_getInputValue(remRdyPIN);
    
    // If MRDY is already low then we must initiate a read because there was
    // a prior MRDY negedge that was missed
    if (!remRdy_state) 
    {
        NPITL_setPM();
        if (taskCBs.remRdyCB)
        {
            transportRemRdyEvent();
            LocRDY_ENABLE();
        }
    }
#endif // NPI_FLOW_CTRL = 1

#if (NPI_FLOW_CTRL == 0)
    // This call will start repeated Uart Reads when Power Savings is disabled
    transportRead();
#endif // NPI_FLOW_CTRL = 0

    NPIUtil_ExitCS(key);
}
示例#21
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
// -----------------------------------------------------------------------------
void NPITLUART_readCallBack(UART_Handle handle, void *ptr, size_t size)
{
#ifndef POWER_SAVING
    uint16_t packetSize;
    uint16_t sofIndex;
#endif //POWER_SAVING
    _npiCSKey_t key;
    key = NPIUtil_EnterCS();

    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(npiBufSize,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) &&
            remRdy_flag)
    {
        RxActive = FALSE;

        // If TX has also completed then we are safe to issue call back
        if (!TxActive && npiTransmitCB)
        {
            if (NPITLUART_validPacketFound() == NPI_SUCCESS)
            {
                // Decrement as to not include trailing FCS byte
                TransportRxLen--;
            }
            else
            {
                // Did not receive valid packet so denote RX length as zero in CB
                TransportRxLen = 0;
            }

            npiTransmitCB(TransportRxLen,TransportTxLen);
        }
    }
    else
    {
        UART_read(uartHandle, &isrRxBuf[0], UART_ISR_BUF_SIZE);
    }
#else
    while (NPITLUART_validPacketFound() == NPI_SUCCESS &&
            npiTransmitCB)
    {
        // The Rx Buffer can contain more than the one valid packet
        // Must only return the number of bytes for the first valid packet and
        // shift the remaining bytes to the beginning of the RX buffer after the
        // CB has completed

        // SOF has already been removed from npiRxBuf here. It is removed
        // when bytes are copied from the ISR Rx buffer to npiRxBuf
        packetSize = (uint16) npiRxBuf[0];
        packetSize += ((uint16) npiRxBuf[1]) << 8;
        packetSize += NPI_UART_MSG_HDR_LEN;

        npiTransmitCB(packetSize,0);

        // Must look for SOF of next packet, first eligible byte is after the
        // FCS of the valid packet
        sofIndex = packetSize + 1;
        while(sofIndex < TransportRxLen)
        {

            if (npiRxBuf[sofIndex] == NPI_UART_MSG_SOF)
            {
                break;
            }

            sofIndex++;
        }

        // New RX len does not include bytes prior to and include the
        // next found SOF byte. If no next SOF byte then len is 0
        TransportRxLen = (TransportRxLen == sofIndex) ? 0 :
                         TransportRxLen - sofIndex - 1;

        // Copy all bytes following next found SOF to beginning of the RX buf
        // and check again for another valid packet
        memcpy(npiRxBuf,&npiRxBuf[sofIndex + 1],TransportRxLen);
    }

    UART_read(uartHandle, &isrRxBuf[0], UART_ISR_BUF_SIZE);
#endif //POWER_SAVING

    NPIUtil_ExitCS(key);
}