// ----------------------------------------------------------------------------- //! \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; }
// ----------------------------------------------------------------------------- //! \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; }
// ----------------------------------------------------------------------------- //! \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); }
// ----------------------------------------------------------------------------- //! \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); }
// ----------------------------------------------------------------------------- //! \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; }
// ----------------------------------------------------------------------------- //! \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); }
// ----------------------------------------------------------------------------- //! \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, ¶ms->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, ¶ms->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); }
// ----------------------------------------------------------------------------- //! \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); }
// ----------------------------------------------------------------------------- //! \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 }
// ----------------------------------------------------------------------------- //! \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, ¶ms->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); }
// ----------------------------------------------------------------------------- //! \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); }
// ----------------------------------------------------------------------------- //! \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, ¶ms->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, ¶ms->portParams.uartParams, NPITL_transmissionCallBack); #elif defined(NPI_USE_SPI) transportOpen(params->portBoardID, ¶ms->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); }
// ----------------------------------------------------------------------------- //! \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); }