123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892 |
- /**************************************************************************************************
- Filename: znp_spi.c
- Revised: $Date: 2010-07-28 18:42:54 -0700 (Wed, 28 Jul 2010) $
- Revision: $Revision: 23203 $
- Description:
- This file contains the interface to the H/W-specific ZNP SPI driver.
- Copyright 2009-2010 Texas Instruments Incorporated. All rights reserved.
- IMPORTANT: Your use of this Software is limited to those specific rights
- granted under the terms of a software license agreement between the user
- who downloaded the software, his/her employer (which must be your employer)
- and Texas Instruments Incorporated (the "License"). You may not use this
- Software unless you agree to abide by the terms of the License. The License
- limits your use, and you acknowledge, that the Software may not be modified,
- copied or distributed unless embedded on a Texas Instruments microcontroller
- or used solely and exclusively in conjunction with a Texas Instruments radio
- frequency transceiver, which is integrated into your product. Other than for
- the foregoing purpose, you may not use, reproduce, copy, prepare derivative
- works of, modify, distribute, perform, display or sell this Software and/or
- its documentation for any purpose.
- YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
- PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
- INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
- NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
- TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
- NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
- LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
- INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
- OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
- OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
- (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
- Should you have any questions regarding your right to use this Software,
- contact Texas Instruments Incorporated at www.TI.com.
- **************************************************************************************************/
- /* ------------------------------------------------------------------------------------------------
- * Includes
- * ------------------------------------------------------------------------------------------------
- */
- #include "comdef.h"
- #include "hal_assert.h"
- #include "hal_dma.h"
- #include "MT_RPC.h"
- #include "OnBoard.h"
- #include "osal.h"
- #if defined POWER_SAVING
- #include "OSAL_PwrMgr.h"
- #endif
- #include "ZDApp.h"
- #include "znp_app.h"
- #include "znp_spi.h"
- /* ------------------------------------------------------------------------------------------------
- * Macros
- * ------------------------------------------------------------------------------------------------
- */
- /*
- * The MAC_ASSERT macro is for use during debugging.
- * The given expression must evaluate as "true" or else fatal error occurs.
- * At that point, the call stack feature of the debugger can pinpoint where the problem occurred.
- *
- * To disable this feature and save code size, the project should define NP_SPI_NODEBUG to TRUE.
- */
- #if !defined ( NP_SPI_NODEBUG )
- #define NP_SPI_NODEBUG TRUE
- #endif
- #if ( NP_SPI_NODEBUG )
- #define NP_SPI_ASSERT( expr )
- #else
- #define NP_SPI_ASSERT( expr) HAL_ASSERT( expr )
- #endif
- #if defined CC2530_MK
- #define DMATRIG_RX HAL_DMA_TRIG_URX0
- #define DMATRIG_TX HAL_DMA_TRIG_UTX0
- #define DMA_UDBUF NP_SPI_U0DBUF
- #else
- #define DMATRIG_RX HAL_DMA_TRIG_URX1
- #define DMATRIG_TX HAL_DMA_TRIG_UTX1
- #define DMA_UDBUF NP_SPI_U1DBUF
- #endif
- #define DMA_RX() \
- st( \
- volatile uint8 clearRx = *((uint8 *)DMA_UDBUF); \
- \
- HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX); \
- \
- HAL_DMA_ARM_CH(HAL_DMA_CH_RX); \
- )
- #define DMA_TX( buf ) \
- st( \
- halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX); \
- \
- HAL_DMA_SET_SOURCE(ch, (buf)); \
- \
- HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_TX); \
- \
- HAL_DMA_ARM_CH(HAL_DMA_CH_TX); \
- \
- HAL_DMA_START_CH(HAL_DMA_CH_TX); \
- )
- #define HAL_DMA_GET_SOURCE( pDesc, src ) \
- st( \
- src = (uint16)(pDesc->srcAddrH) << 8; \
- src += pDesc->srcAddrL; \
- )
- /* ------------------------------------------------------------------------------------------------
- * Constants
- * ------------------------------------------------------------------------------------------------
- */
- #define NP_SPI_U0DBUF 0x70C1
- #define NP_SPI_U1DBUF 0x70F9
- /* UxCSR - USART Control and Status Register. */
- #define CSR_MODE 0x80
- #define CSR_RE 0x40
- #define CSR_SLAVE 0x20
- #define CSR_FE 0x10
- #define CSR_ERR 0x08
- #define CSR_RX_BYTE 0x04
- #define CSR_TX_BYTE 0x02
- #define CSR_ACTIVE 0x01
- /* UxUCR - USART UART Control Register. */
- #define UCR_FLUSH 0x80
- #define UCR_FLOW 0x40
- #define UCR_D9 0x20
- #define UCR_BIT9 0x10
- #define UCR_PARITY 0x08
- #define UCR_SPB 0x04
- #define UCR_STOP 0x02
- #define UCR_START 0x01
- #define UTX0IE 0x04
- #define UTX1IE 0x08
- #define NP_SPI_RX_SREQ_EVENT ZNP_SPI_RX_SREQ_EVENT
- #define NP_SPI_RX_AREQ_EVENT ZNP_SPI_RX_AREQ_EVENT
- /* Reference data sheet section 8.2.4: When using variable-length transfers, then LEN
- * should be set to the largest allowed transfer length plus one.
- */
- #define NP_SPI_BUF_LEN (MT_RPC_DATA_MAX + MT_RPC_FRAME_HDR_SZ + 1)
- #if defined CC2530_MK
- #define NP_RDYIn_BIT BV(0)
- #define NP_RDYIn P2_0
- #define NP_RDYOut P1_0
- #define NP_RDYOut_BIT BV(0)
- #elif !defined CC2530ZNP_MK
- #define NP_RDYIn_BIT BV(3)
- #define NP_RDYIn P0_3
- #define NP_RDYOut P0_4
- #define NP_RDYOut_BIT BV(4)
- #endif
- #define NP_CSR_MODE BV(5) // CSR_SLAVE
- /* ------------------------------------------------------------------------------------------------
- * TypeDefs
- * ------------------------------------------------------------------------------------------------
- */
- typedef enum
- {
- NP_SPI_IDLE, /* Idle, no transaction in progress. */
- NP_SPI_MRDY, /* Idle, but got MRDY ISR, so waiting to enable the RX DMA. */
- NP_SPI_WAIT_RX, /* Waiting for RX to complete. */
- NP_SPI_WAIT_TX, /* Waiting for TX to complete. */
- NP_SPI_WAIT_AREQ, /* Waiting for asynchronous request to finish processing. */
- NP_SPI_WAIT_SREQ /* Waiting for a synchronous request to finish processing. */
- } spiState_t;
- /* ------------------------------------------------------------------------------------------------
- * Local Variables
- * ------------------------------------------------------------------------------------------------
- */
- static uint8 npSpiBuf[NP_SPI_BUF_LEN];
- static volatile spiState_t npSpiState;
- /* ------------------------------------------------------------------------------------------------
- * Local Functions
- * ------------------------------------------------------------------------------------------------
- */
- static void dmaInit(void);
- /**************************************************************************************************
- * @fn dmaInit
- *
- * @brief This function initializes the DMA for the SPI driver.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- static void dmaInit(void)
- {
- halDMADesc_t *ch;
- /* Setup Tx by DMA. */
- ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX);
- /* The start address of the source and destination. */
- HAL_DMA_SET_SOURCE(ch, npSpiBuf);
- HAL_DMA_SET_DEST(ch, DMA_UDBUF);
- /* Transfer the first byte + the number of bytes indicated by the first byte + 2 more bytes. */
- HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_1_P_VALOFFIRST_P_2);
- HAL_DMA_SET_LEN(ch, NP_SPI_BUF_LEN);
- /* One byte is transferred each time. */
- HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE);
- /* The bytes are transferred 1-by-1 on Tx Complete trigger. */
- HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE);
- HAL_DMA_SET_TRIG_SRC(ch, DMATRIG_TX);
- /* The source address is decremented by 1 byte after each transfer. */
- HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_1);
- /* The destination address is constant - the Tx Data Buffer. */
- HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_0);
- /* The DMA shall issue an IRQ upon completion. */
- HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_ENABLE);
- /* Xfer all 8 bits of a byte xfer. */
- HAL_DMA_SET_M8(ch, HAL_DMA_M8_USE_8_BITS);
- /* DMA has highest priority for memory access. */
- HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH);
- /* Setup Rx by DMA. */
- ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_RX);
- /* The start address of the source and destination. */
- HAL_DMA_SET_SOURCE(ch, DMA_UDBUF);
- HAL_DMA_SET_DEST(ch, npSpiBuf);
- /* Transfer the first byte + the number of bytes indicated by the first byte + 2 more bytes. */
- HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_1_P_VALOFFIRST_P_2);
- HAL_DMA_SET_LEN(ch, NP_SPI_BUF_LEN);
- HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE);
- /* The bytes are transferred 1-by-1 on Rx Complete trigger. */
- HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE);
- HAL_DMA_SET_TRIG_SRC(ch, DMATRIG_RX);
- /* The source address is constant - the Rx Data Buffer. */
- HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_0);
- /* The destination address is incremented by 1 byte after each transfer. */
- HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_1);
- /* The DMA shall issue an IRQ upon completion. */
- HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_ENABLE);
- /* Xfer all 8 bits of a byte xfer. */
- HAL_DMA_SET_M8(ch, HAL_DMA_M8_USE_8_BITS);
- /* DMA has highest priority for memory access. */
- HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH);
- }
- /**************************************************************************************************
- * @fn npSpiInit
- *
- * @brief This function is called to set up the SPI interface.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- #if defined CC2530_MK
- void npSpiInit(void) // TODO - hard-coded for USART0 alt1 SPI for now.
- {
- if (ZNP_CFG1_UART == znpCfg1)
- {
- return;
- }
- /* Set bit order to MSB */
- U0GCR |= BV(5);
- /* Set UART0 I/O to alternate 1 location on P1 pins. */
- //PERCFG |= 0x02; /* U1CFG */
- /* Mode select UART1 SPI Mode as slave. */
- U0CSR = NP_CSR_MODE;
- /* Select peripheral function on I/O pins. */
- P0SEL |= 0x3C; /* SELP0_[5:2] */
- /* Give UART1 priority over Timer3. */
- //P2SEL &= ~0x20; /* PRI2P1 */
- /* Set RDY to inactive high. */
- NP_RDYOut = 1;
- /* Select general purpose on I/O pins. */
- P1SEL &= ~(NP_RDYOut_BIT); /* P1.0 SRDY - GPIO */
- P2SEL &= ~(NP_RDYIn_BIT); /* P2.0 MRDY - GPIO */
- /* Select GPIO direction */
- P1DIR |= NP_RDYOut_BIT; /* P1.0 SRDY - OUT */
- P2DIR &= ~NP_RDYIn_BIT; /* P2.0 MRDY - IN */
- /* Falling edge on P2 pins triggers interrupt. */
- PICTL |= BV(3); /* P2ICON */
- /* Trigger an interrupt on MRDY input. */
- P2IFG &= ~NP_RDYIn_BIT;
- P2IEN |= NP_RDYIn_BIT;
- IEN2 |= 0x02;
- dmaInit();
- U0CSR |= CSR_RE;
- }
- #else
- void npSpiInit(void)
- {
- if (ZNP_CFG1_UART == znpCfg1)
- {
- return;
- }
- /* Set bit order to MSB */
- U1GCR |= BV(5);
- /* Set UART1 I/O to alternate 2 location on P1 pins. */
- PERCFG |= 0x02; /* U1CFG */
- /* Mode select UART1 SPI Mode as slave. */
- U1CSR = NP_CSR_MODE;
- /* Select peripheral function on I/O pins. */
- P1SEL |= 0xF0; /* SELP1_[7:4] */
- /* Give UART1 priority over Timer3. */
- P2SEL &= ~0x20; /* PRI2P1 */
- /* Set RDY to inactive high. */
- NP_RDYOut = 1;
- /* Select general purpose on I/O pins. */
- P0SEL &= ~(NP_RDYIn_BIT); /* P0.3 MRDY - GPIO */
- P0SEL &= ~(NP_RDYOut_BIT); /* P0.4 SRDY - GPIO */
- /* Select GPIO direction */
- P0DIR &= ~NP_RDYIn_BIT; /* P0.3 MRDY - IN */
- P0DIR |= NP_RDYOut_BIT; /* P0.4 SRDY - OUT */
- P0INP &= ~NP_RDYIn_BIT; /* Pullup/down enable of MRDY input. */
- P2INP &= ~BV(5); /* Pullup all P0 inputs. */
- /* Falling edge on P0 pins triggers interrupt. */
- PICTL |= BV(0); /* P0ICON */
- /* Trigger an interrupt on MRDY input. */
- P0IFG &= ~NP_RDYIn_BIT;
- P0IEN |= NP_RDYIn_BIT;
- P0IE = 1;
- dmaInit();
- U1CSR |= CSR_RE;
- }
- #endif
- /**************************************************************************************************
- * @fn npSpiMonitor
- *
- * @brief This function monitors the SPI signals for error conditions and for the end of a
- * transaction. If an error is detected it attempts to recover.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- void npSpiMonitor(void)
- {
- if (ZNP_CFG1_UART == znpCfg1)
- {
- return;
- }
- #if ZNP_RUN_WDOG
- if ((devState != DEV_HOLD) && (npSpiState == NP_SPI_IDLE))
- {
- // Enable the watchdog for 1 second period and pet it.
- WatchDogEnable( WDTIMX );
- }
- #endif
- switch (npSpiState)
- {
- case NP_SPI_IDLE:
- NP_SPI_ASSERT((P1IFG & NP_RDYIn_BIT) == 0);
- break;
- #if defined POWER_SAVING
- case NP_SPI_MRDY:
- npSpiState = NP_SPI_WAIT_RX;
- DMA_RX();
- NP_RDYOut = 0;
- break;
- #endif
- case NP_SPI_WAIT_RX:
- NP_SPI_ASSERT((HAL_DMA_CHECK_IRQ(HAL_DMA_CH_RX)) == 0);
- break;
- case NP_SPI_WAIT_TX:
- NP_SPI_ASSERT((HAL_DMA_CHECK_IRQ(HAL_DMA_CH_TX)) == 0);
- break;
- case NP_SPI_WAIT_AREQ:
- break;
- default:
- NP_SPI_ASSERT(0);
- break;
- }
- if (npSpiState == NP_SPI_IDLE)
- {
- *((uint8 *)DMA_UDBUF) = 0; // Clear the SPI Tx buffer to zero.
- /* Poll for MRDY in case it was set before slave had setup the ISR.
- * Also, async responses may get queued, so flush them out here.
- */
- if ((NP_RDYIn == 0) || (npSpiReadyCallback()))
- {
- npSpiAReqReady();
- }
- }
- else
- {
- halIntState_t his;
- HAL_ENTER_CRITICAL_SECTION(his);
- if (((npSpiState == NP_SPI_WAIT_RX) &&
- (!HAL_DMA_CH_ARMED(HAL_DMA_CH_RX) && !HAL_DMA_CHECK_IRQ(HAL_DMA_CH_RX)))
- || ((npSpiState == NP_SPI_WAIT_TX) &&
- (!HAL_DMA_CH_ARMED(HAL_DMA_CH_TX) && !HAL_DMA_CHECK_IRQ(HAL_DMA_CH_TX))))
- {
- HAL_EXIT_CRITICAL_SECTION(his);
- if (npSpiState == NP_SPI_WAIT_RX)
- {
- npSpiRxIsr();
- }
- else // if (npSpiState == NP_SPI_WAIT_TX)
- {
- npSpiTxIsr();
- }
- }
- else
- {
- HAL_EXIT_CRITICAL_SECTION(his);
- }
- }
- #if defined POWER_SAVING
- /* A simple ZAP application sending a unicast at 2-Hz was seen to bog down to < 1-Hz OTA unicast
- * when the ZNP was configured to be a ZED (i.e. POWER_SAVING was enabled). So adding this delay
- * of only 10 msecs before re-enabling CONSERVE showed that the problem was fixed while still
- * allowing the ZNP to enter sleep.
- */
- static uint8 znpSpiActiveShdw;
- if (ZG_DEVICE_ENDDEVICE_TYPE && (npSpiState == NP_SPI_IDLE))
- {
- if (znpSpiActiveShdw)
- {
- uint8 rxOnIdle;
- (void)ZMacGetReq(ZMacRxOnIdle, &rxOnIdle);
- if (!rxOnIdle)
- {
- znpSpiActiveShdw = FALSE;
- if (ZSuccess != osal_start_timerEx(znpTaskId, ZNP_PWRMGR_CONSERVE_EVENT,
- ZNP_PWRMGR_CONSERVE_DELAY))
- {
- (void)osal_set_event(znpTaskId, ZNP_PWRMGR_CONSERVE_EVENT);
- }
- }
- }
- }
- else if (!znpSpiActiveShdw)
- {
- znpSpiActiveShdw = TRUE;
- (void)osal_stop_timerEx(znpTaskId, ZNP_PWRMGR_CONSERVE_EVENT);
- (void)osal_clear_event(znpTaskId, ZNP_PWRMGR_CONSERVE_EVENT);
- (void)osal_pwrmgr_task_state(znpTaskId, PWRMGR_HOLD);
- }
- #endif
- }
- /**************************************************************************************************
- * @fn npSpiSRspAlloc
- *
- * @brief This function is called by MT to allocate a buffer in which to build an SRSP frame.
- * MT must only call this function after processing a received SREQ frame.
- *
- * input parameters
- *
- * @param len - Length of the buffer required.
- *
- * output parameters
- *
- * None.
- *
- * @return NULL for failure; a pointer to the npSpiBuf on success. Success is determined by
- * the correct npSpiState and H/W signals as well as a valid length request.
- **************************************************************************************************
- */
- uint8 *npSpiSRspAlloc(uint8 len)
- {
- if (npSpiState == NP_SPI_WAIT_SREQ)
- {
- return npSpiBuf;
- }
- else
- {
- return NULL;
- }
- }
- /**************************************************************************************************
- * @fn npSpiAReqAlloc
- *
- * @brief This function is called by MT to allocate a buffer in which to buld an AREQ frame.
- *
- * input parameters
- *
- * @param len - Length of the buffer required.
- *
- * output parameters
- *
- * None.
- *
- * @return NULL for failure; otherwise a pointer to the data of an osal message.
- **************************************************************************************************
- */
- uint8 *npSpiAReqAlloc(uint8 len)
- {
- return osal_msg_allocate(len + MT_RPC_FRAME_HDR_SZ);
- }
- /**************************************************************************************************
- * @fn npSpiSRspReady
- *
- * @brief This function is called by MT to notify SPI driver that an SRSP is ready to Tx.
- *
- * input parameters
- *
- * @param pBuf - Pointer to the buffer to transmit on the SPI.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- void npSpiSRspReady(uint8 *pBuf)
- {
- if ((npSpiState == NP_SPI_WAIT_SREQ) && (NP_RDYOut == 0))
- {
- npSpiState = NP_SPI_WAIT_TX;
- DMA_TX( pBuf );
- NP_RDYOut = 1;
- }
- }
- /**************************************************************************************************
- * @fn npSpiAReqReady
- *
- * @brief This function is called by MT to notify the SPI driver that an AREQ frame is ready
- * to be transmitted.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- void npSpiAReqReady(void)
- {
- halIntState_t intState;
- HAL_ENTER_CRITICAL_SECTION(intState);
- if (npSpiState == NP_SPI_IDLE)
- {
- npSpiState = NP_SPI_WAIT_RX;
- DMA_RX();
- NP_RDYOut = 0;
- }
- HAL_EXIT_CRITICAL_SECTION(intState);
- }
- /**************************************************************************************************
- * @fn npSpiAReqComplete
- *
- * @brief This function is called by MT to notify the SPI driver that the processing of a
- * received AREQ is complete.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- void npSpiAReqComplete(void)
- {
- if (npSpiState == NP_SPI_WAIT_AREQ)
- {
- npSpiState = NP_SPI_IDLE;
- }
- }
- /**************************************************************************************************
- * @fn npSpiGetReqBuf
- *
- * @brief This function is called by the application to get the buffer containing the
- * currently received AREQ or SREQ.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return Pointer to the buffer containing the currently received AREQ or SREQ.
- **************************************************************************************************
- */
- uint8 *npSpiGetReqBuf(void)
- {
- if (npSpiState != NP_SPI_IDLE)
- {
- return npSpiBuf;
- }
- else
- {
- return NULL;
- }
- }
- /**************************************************************************************************
- * @fn npSpiMrdyIsr
- *
- * @brief This function is called when a GPIO falling-edge interrupt occurs on the MRDY.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- void npSpiMrdyIsr(void)
- {
- if (npSpiState == NP_SPI_IDLE)
- {
- #if defined POWER_SAVING
- if (ZG_DEVICE_ENDDEVICE_TYPE)
- {
- npSpiState = NP_SPI_MRDY;
- }
- else
- #endif
- {
- npSpiState = NP_SPI_WAIT_RX;
- DMA_RX();
- NP_RDYOut = 0;
- }
- }
- }
- /**************************************************************************************************
- * @fn npSpiRxIsr
- *
- * @brief This function handles the DMA Rx complete interrupt.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- void npSpiRxIsr(void)
- {
- mtRpcCmdType_t type = (mtRpcCmdType_t)(npSpiBuf[1] & MT_RPC_CMD_TYPE_MASK);
- uint8 *pBuf, rdy = 1;
- NP_SPI_ASSERT(npSpiState == NP_SPI_WAIT_RX);
- switch (type)
- {
- case MT_RPC_CMD_POLL:
- if ( (pBuf = npSpiPollCallback()) == NULL )
- {
- pBuf = npSpiBuf;
- npSpiBuf[0] = 0;
- npSpiBuf[1] = 0;
- npSpiBuf[2] = 0;
- }
- npSpiState = NP_SPI_WAIT_TX;
- DMA_TX(pBuf);
- break;
- case MT_RPC_CMD_SREQ:
- npSpiState = NP_SPI_WAIT_SREQ;
- osal_set_event(znpTaskId, ZNP_SPI_RX_SREQ_EVENT);
- rdy = 0;
- 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;
- }
- NP_RDYOut = rdy;
- }
- /**************************************************************************************************
- * @fn npSpiTxIsr
- *
- * @brief This function handles the DMA Tx complete interrupt.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- void npSpiTxIsr(void)
- {
- halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX);
- uint16 src;
- NP_SPI_ASSERT(npSpiState == NP_SPI_WAIT_TX);
- HAL_DMA_GET_SOURCE( ch, src );
- if ((uint8 *)src != npSpiBuf)
- {
- osal_msg_deallocate((uint8 *)src);
- }
- npSpiState = NP_SPI_IDLE;
- }
- /**************************************************************************************************
- * @fn npSpiIdle
- *
- * @brief This function returns true if SPI is idle and there is no queued data.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return True if SPI is idle with no quequed data.
- **************************************************************************************************
- */
- bool npSpiIdle(void)
- {
- return (npSpiState == NP_SPI_IDLE && !npSpiReadyCallback());
- }
- /**************************************************************************************************
- * @fn portN-Isr
- *
- * @brief This function handles the PORT-N interrupt.
- *
- * input parameters
- *
- * None.
- *
- * output parameters
- *
- * None.
- *
- * @return None.
- **************************************************************************************************
- */
- #if defined CC2530_MK
- HAL_ISR_FUNCTION(port2Isr, P2INT_VECTOR)
- {
- P2IFG = 0;
- P2IF = 0;
- #else
- HAL_ISR_FUNCTION(port0Isr, P0INT_VECTOR)
- {
- P0IFG = 0;
- P0IF = 0;
- #endif
- // Knowing which pin requires a #define from _hal_uart_dma.c
- //if (P0IFG & NP_RDYIn_BIT)
- {
- if (ZNP_CFG1_UART == znpCfg1)
- {
- osal_set_event(znpTaskId, ZNP_UART_TX_READY_EVENT);
- }
- else
- {
- npSpiMrdyIsr();
- }
- }
- }
- /**************************************************************************************************
- */
|