/************************************************************************************************** * @fn npSpiRxIsr * * @brief This function handles the DMA Rx complete interrupt. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ void HalSpiRxIsr(void) { uint8 type = halSpiBuf[1] & RPC_CMD_TYPE_MASK; uint8 *pBuf, rdy = 1; NP_SPI_ASSERT(halSpiState == NP_SPI_WAIT_RX); switch (type) { case RPC_CMD_AREQ: // call client with message type so it can schedule an OSAL event // ISN'T THIS PROBLEMATIC? IF THE BUFFER HASN'T BEEN COPIED, OR THE DMA // POINTER CHANGED, WHAT'S TO STOP THE MASTER FROM SENDING ANOTHER AREQ? // THE STATE MIGHT CAUSE AN ASSERT, BUT THIS DOESN'T SEEM LIKE THE RIGHT // SOLUTION. HAL_SPI_DBG_LOG(0x12); npSpiReqCallback( RPC_CMD_AREQ ); halSpiState = NP_SPI_WAIT_AREQ; break; case RPC_CMD_SREQ: // synchronous request received, so need to send back a synchronous reply // call client with message type so it can schedule an OSAL event HAL_SPI_DBG_LOG(0x13); npSpiReqCallback( RPC_CMD_SREQ ); halSpiState = NP_SPI_WAIT_TX; rdy = 0; // keep SRDY asserted until SRSP is ready to be sent, then deassert so master can read back SRSP break; case RPC_CMD_POLL: // callback to assign pBuf with AREQ to send from slave // Note: this AREQ was already queued by the slave when it wanted to send // an asynchronous command to the master by asserting SRDY. HAL_SPI_DBG_LOG(0x14); if ( (pBuf = npSpiPollCallback()) == NULL ) { // nothing was queued, which is odd, so just send an empty frame? halSpiBuf[0] = 0; halSpiBuf[1] = 0; halSpiBuf[2] = 0; pBuf = halSpiBuf; } halSpiState = NP_SPI_WAIT_TX; DMA_TX(pBuf); break; default: HAL_SPI_DBG_LOG(0x15); halSpiState = NP_SPI_IDLE; break; } NP_RDYOut = rdy; }
/************************************************************************************************** * @fn npSpiRxIsr * * @brief This function handles the DMA Rx complete interrupt. * * input parameters * * None. * * output parameters * * None. * * @return None. ************************************************************************************************** */ void npSpiRxIsr(void) { uint8 *pBuf; mtRpcCmdType_t type = (mtRpcCmdType_t)(npSpiBuf[1] & MT_RPC_CMD_TYPE_MASK); NP_SPI_ASSERT(npSpiState == NP_SPI_WAIT_RX); switch (type) { case MT_RPC_CMD_POLL: npSpiState = NP_SPI_WAIT_TX; if ((pBuf = npSpiPollCallback()) != NULL) { /* Send TX packet using uDMA */ spi_tx(pBuf); osal_msg_deallocate((uint8 *)pBuf); } else { /* If there is no data in the queue, send 3 zeros. */ pBuf = npSpiBuf; npSpiBuf[0] = npSpiBuf[1] = npSpiBuf[2] = 0; /* Send TX packet using uDMA */ spi_tx(pBuf); } break; case MT_RPC_CMD_SREQ: npSpiState = NP_SPI_WAIT_SREQ; osal_set_event(znpTaskId, ZNP_SPI_RX_SREQ_EVENT); break; case MT_RPC_CMD_AREQ: npSpiState = NP_SPI_WAIT_AREQ; osal_set_event(znpTaskId, ZNP_SPI_RX_AREQ_EVENT); break; default: npSpiState = NP_SPI_IDLE; break; } }