znp_spi.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. /**************************************************************************************************
  2. Filename: znp_spi.c
  3. Revised: $Date: 2010-07-28 18:42:54 -0700 (Wed, 28 Jul 2010) $
  4. Revision: $Revision: 23203 $
  5. Description:
  6. This file contains the interface to the H/W-specific ZNP SPI driver.
  7. Copyright 2009-2010 Texas Instruments Incorporated. All rights reserved.
  8. IMPORTANT: Your use of this Software is limited to those specific rights
  9. granted under the terms of a software license agreement between the user
  10. who downloaded the software, his/her employer (which must be your employer)
  11. and Texas Instruments Incorporated (the "License"). You may not use this
  12. Software unless you agree to abide by the terms of the License. The License
  13. limits your use, and you acknowledge, that the Software may not be modified,
  14. copied or distributed unless embedded on a Texas Instruments microcontroller
  15. or used solely and exclusively in conjunction with a Texas Instruments radio
  16. frequency transceiver, which is integrated into your product. Other than for
  17. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  18. works of, modify, distribute, perform, display or sell this Software and/or
  19. its documentation for any purpose.
  20. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  21. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  22. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  23. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  24. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  25. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  26. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  27. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  28. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  29. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  30. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  31. Should you have any questions regarding your right to use this Software,
  32. contact Texas Instruments Incorporated at www.TI.com.
  33. **************************************************************************************************/
  34. /* ------------------------------------------------------------------------------------------------
  35. * Includes
  36. * ------------------------------------------------------------------------------------------------
  37. */
  38. #include "comdef.h"
  39. #include "hal_assert.h"
  40. #include "hal_dma.h"
  41. #include "MT_RPC.h"
  42. #include "OnBoard.h"
  43. #include "osal.h"
  44. #if defined POWER_SAVING
  45. #include "OSAL_PwrMgr.h"
  46. #endif
  47. #include "ZDApp.h"
  48. #include "znp_app.h"
  49. #include "znp_spi.h"
  50. /* ------------------------------------------------------------------------------------------------
  51. * Macros
  52. * ------------------------------------------------------------------------------------------------
  53. */
  54. /*
  55. * The MAC_ASSERT macro is for use during debugging.
  56. * The given expression must evaluate as "true" or else fatal error occurs.
  57. * At that point, the call stack feature of the debugger can pinpoint where the problem occurred.
  58. *
  59. * To disable this feature and save code size, the project should define NP_SPI_NODEBUG to TRUE.
  60. */
  61. #if !defined ( NP_SPI_NODEBUG )
  62. #define NP_SPI_NODEBUG TRUE
  63. #endif
  64. #if ( NP_SPI_NODEBUG )
  65. #define NP_SPI_ASSERT( expr )
  66. #else
  67. #define NP_SPI_ASSERT( expr) HAL_ASSERT( expr )
  68. #endif
  69. #if defined CC2530_MK
  70. #define DMATRIG_RX HAL_DMA_TRIG_URX0
  71. #define DMATRIG_TX HAL_DMA_TRIG_UTX0
  72. #define DMA_UDBUF NP_SPI_U0DBUF
  73. #else
  74. #define DMATRIG_RX HAL_DMA_TRIG_URX1
  75. #define DMATRIG_TX HAL_DMA_TRIG_UTX1
  76. #define DMA_UDBUF NP_SPI_U1DBUF
  77. #endif
  78. #define DMA_RX() \
  79. st( \
  80. volatile uint8 clearRx = *((uint8 *)DMA_UDBUF); \
  81. \
  82. HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX); \
  83. \
  84. HAL_DMA_ARM_CH(HAL_DMA_CH_RX); \
  85. )
  86. #define DMA_TX( buf ) \
  87. st( \
  88. halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX); \
  89. \
  90. HAL_DMA_SET_SOURCE(ch, (buf)); \
  91. \
  92. HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_TX); \
  93. \
  94. HAL_DMA_ARM_CH(HAL_DMA_CH_TX); \
  95. \
  96. HAL_DMA_START_CH(HAL_DMA_CH_TX); \
  97. )
  98. #define HAL_DMA_GET_SOURCE( pDesc, src ) \
  99. st( \
  100. src = (uint16)(pDesc->srcAddrH) << 8; \
  101. src += pDesc->srcAddrL; \
  102. )
  103. /* ------------------------------------------------------------------------------------------------
  104. * Constants
  105. * ------------------------------------------------------------------------------------------------
  106. */
  107. #define NP_SPI_U0DBUF 0x70C1
  108. #define NP_SPI_U1DBUF 0x70F9
  109. /* UxCSR - USART Control and Status Register. */
  110. #define CSR_MODE 0x80
  111. #define CSR_RE 0x40
  112. #define CSR_SLAVE 0x20
  113. #define CSR_FE 0x10
  114. #define CSR_ERR 0x08
  115. #define CSR_RX_BYTE 0x04
  116. #define CSR_TX_BYTE 0x02
  117. #define CSR_ACTIVE 0x01
  118. /* UxUCR - USART UART Control Register. */
  119. #define UCR_FLUSH 0x80
  120. #define UCR_FLOW 0x40
  121. #define UCR_D9 0x20
  122. #define UCR_BIT9 0x10
  123. #define UCR_PARITY 0x08
  124. #define UCR_SPB 0x04
  125. #define UCR_STOP 0x02
  126. #define UCR_START 0x01
  127. #define UTX0IE 0x04
  128. #define UTX1IE 0x08
  129. #define NP_SPI_RX_SREQ_EVENT ZNP_SPI_RX_SREQ_EVENT
  130. #define NP_SPI_RX_AREQ_EVENT ZNP_SPI_RX_AREQ_EVENT
  131. /* Reference data sheet section 8.2.4: When using variable-length transfers, then LEN
  132. * should be set to the largest allowed transfer length plus one.
  133. */
  134. #define NP_SPI_BUF_LEN (MT_RPC_DATA_MAX + MT_RPC_FRAME_HDR_SZ + 1)
  135. #if defined CC2530_MK
  136. #define NP_RDYIn_BIT BV(0)
  137. #define NP_RDYIn P2_0
  138. #define NP_RDYOut P1_0
  139. #define NP_RDYOut_BIT BV(0)
  140. #elif !defined CC2530ZNP_MK
  141. #define NP_RDYIn_BIT BV(3)
  142. #define NP_RDYIn P0_3
  143. #define NP_RDYOut P0_4
  144. #define NP_RDYOut_BIT BV(4)
  145. #endif
  146. #define NP_CSR_MODE BV(5) // CSR_SLAVE
  147. /* ------------------------------------------------------------------------------------------------
  148. * TypeDefs
  149. * ------------------------------------------------------------------------------------------------
  150. */
  151. typedef enum
  152. {
  153. NP_SPI_IDLE, /* Idle, no transaction in progress. */
  154. NP_SPI_MRDY, /* Idle, but got MRDY ISR, so waiting to enable the RX DMA. */
  155. NP_SPI_WAIT_RX, /* Waiting for RX to complete. */
  156. NP_SPI_WAIT_TX, /* Waiting for TX to complete. */
  157. NP_SPI_WAIT_AREQ, /* Waiting for asynchronous request to finish processing. */
  158. NP_SPI_WAIT_SREQ /* Waiting for a synchronous request to finish processing. */
  159. } spiState_t;
  160. /* ------------------------------------------------------------------------------------------------
  161. * Local Variables
  162. * ------------------------------------------------------------------------------------------------
  163. */
  164. static uint8 npSpiBuf[NP_SPI_BUF_LEN];
  165. static volatile spiState_t npSpiState;
  166. /* ------------------------------------------------------------------------------------------------
  167. * Local Functions
  168. * ------------------------------------------------------------------------------------------------
  169. */
  170. static void dmaInit(void);
  171. /**************************************************************************************************
  172. * @fn dmaInit
  173. *
  174. * @brief This function initializes the DMA for the SPI driver.
  175. *
  176. * input parameters
  177. *
  178. * None.
  179. *
  180. * output parameters
  181. *
  182. * None.
  183. *
  184. * @return None.
  185. **************************************************************************************************
  186. */
  187. static void dmaInit(void)
  188. {
  189. halDMADesc_t *ch;
  190. /* Setup Tx by DMA. */
  191. ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX);
  192. /* The start address of the source and destination. */
  193. HAL_DMA_SET_SOURCE(ch, npSpiBuf);
  194. HAL_DMA_SET_DEST(ch, DMA_UDBUF);
  195. /* Transfer the first byte + the number of bytes indicated by the first byte + 2 more bytes. */
  196. HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_1_P_VALOFFIRST_P_2);
  197. HAL_DMA_SET_LEN(ch, NP_SPI_BUF_LEN);
  198. /* One byte is transferred each time. */
  199. HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE);
  200. /* The bytes are transferred 1-by-1 on Tx Complete trigger. */
  201. HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE);
  202. HAL_DMA_SET_TRIG_SRC(ch, DMATRIG_TX);
  203. /* The source address is decremented by 1 byte after each transfer. */
  204. HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_1);
  205. /* The destination address is constant - the Tx Data Buffer. */
  206. HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_0);
  207. /* The DMA shall issue an IRQ upon completion. */
  208. HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_ENABLE);
  209. /* Xfer all 8 bits of a byte xfer. */
  210. HAL_DMA_SET_M8(ch, HAL_DMA_M8_USE_8_BITS);
  211. /* DMA has highest priority for memory access. */
  212. HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH);
  213. /* Setup Rx by DMA. */
  214. ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_RX);
  215. /* The start address of the source and destination. */
  216. HAL_DMA_SET_SOURCE(ch, DMA_UDBUF);
  217. HAL_DMA_SET_DEST(ch, npSpiBuf);
  218. /* Transfer the first byte + the number of bytes indicated by the first byte + 2 more bytes. */
  219. HAL_DMA_SET_VLEN(ch, HAL_DMA_VLEN_1_P_VALOFFIRST_P_2);
  220. HAL_DMA_SET_LEN(ch, NP_SPI_BUF_LEN);
  221. HAL_DMA_SET_WORD_SIZE(ch, HAL_DMA_WORDSIZE_BYTE);
  222. /* The bytes are transferred 1-by-1 on Rx Complete trigger. */
  223. HAL_DMA_SET_TRIG_MODE(ch, HAL_DMA_TMODE_SINGLE);
  224. HAL_DMA_SET_TRIG_SRC(ch, DMATRIG_RX);
  225. /* The source address is constant - the Rx Data Buffer. */
  226. HAL_DMA_SET_SRC_INC(ch, HAL_DMA_SRCINC_0);
  227. /* The destination address is incremented by 1 byte after each transfer. */
  228. HAL_DMA_SET_DST_INC(ch, HAL_DMA_DSTINC_1);
  229. /* The DMA shall issue an IRQ upon completion. */
  230. HAL_DMA_SET_IRQ(ch, HAL_DMA_IRQMASK_ENABLE);
  231. /* Xfer all 8 bits of a byte xfer. */
  232. HAL_DMA_SET_M8(ch, HAL_DMA_M8_USE_8_BITS);
  233. /* DMA has highest priority for memory access. */
  234. HAL_DMA_SET_PRIORITY(ch, HAL_DMA_PRI_HIGH);
  235. }
  236. /**************************************************************************************************
  237. * @fn npSpiInit
  238. *
  239. * @brief This function is called to set up the SPI interface.
  240. *
  241. * input parameters
  242. *
  243. * None.
  244. *
  245. * output parameters
  246. *
  247. * None.
  248. *
  249. * @return None.
  250. **************************************************************************************************
  251. */
  252. #if defined CC2530_MK
  253. void npSpiInit(void) // TODO - hard-coded for USART0 alt1 SPI for now.
  254. {
  255. if (ZNP_CFG1_UART == znpCfg1)
  256. {
  257. return;
  258. }
  259. /* Set bit order to MSB */
  260. U0GCR |= BV(5);
  261. /* Set UART0 I/O to alternate 1 location on P1 pins. */
  262. //PERCFG |= 0x02; /* U1CFG */
  263. /* Mode select UART1 SPI Mode as slave. */
  264. U0CSR = NP_CSR_MODE;
  265. /* Select peripheral function on I/O pins. */
  266. P0SEL |= 0x3C; /* SELP0_[5:2] */
  267. /* Give UART1 priority over Timer3. */
  268. //P2SEL &= ~0x20; /* PRI2P1 */
  269. /* Set RDY to inactive high. */
  270. NP_RDYOut = 1;
  271. /* Select general purpose on I/O pins. */
  272. P1SEL &= ~(NP_RDYOut_BIT); /* P1.0 SRDY - GPIO */
  273. P2SEL &= ~(NP_RDYIn_BIT); /* P2.0 MRDY - GPIO */
  274. /* Select GPIO direction */
  275. P1DIR |= NP_RDYOut_BIT; /* P1.0 SRDY - OUT */
  276. P2DIR &= ~NP_RDYIn_BIT; /* P2.0 MRDY - IN */
  277. /* Falling edge on P2 pins triggers interrupt. */
  278. PICTL |= BV(3); /* P2ICON */
  279. /* Trigger an interrupt on MRDY input. */
  280. P2IFG &= ~NP_RDYIn_BIT;
  281. P2IEN |= NP_RDYIn_BIT;
  282. IEN2 |= 0x02;
  283. dmaInit();
  284. U0CSR |= CSR_RE;
  285. }
  286. #else
  287. void npSpiInit(void)
  288. {
  289. if (ZNP_CFG1_UART == znpCfg1)
  290. {
  291. return;
  292. }
  293. /* Set bit order to MSB */
  294. U1GCR |= BV(5);
  295. /* Set UART1 I/O to alternate 2 location on P1 pins. */
  296. PERCFG |= 0x02; /* U1CFG */
  297. /* Mode select UART1 SPI Mode as slave. */
  298. U1CSR = NP_CSR_MODE;
  299. /* Select peripheral function on I/O pins. */
  300. P1SEL |= 0xF0; /* SELP1_[7:4] */
  301. /* Give UART1 priority over Timer3. */
  302. P2SEL &= ~0x20; /* PRI2P1 */
  303. /* Set RDY to inactive high. */
  304. NP_RDYOut = 1;
  305. /* Select general purpose on I/O pins. */
  306. P0SEL &= ~(NP_RDYIn_BIT); /* P0.3 MRDY - GPIO */
  307. P0SEL &= ~(NP_RDYOut_BIT); /* P0.4 SRDY - GPIO */
  308. /* Select GPIO direction */
  309. P0DIR &= ~NP_RDYIn_BIT; /* P0.3 MRDY - IN */
  310. P0DIR |= NP_RDYOut_BIT; /* P0.4 SRDY - OUT */
  311. P0INP &= ~NP_RDYIn_BIT; /* Pullup/down enable of MRDY input. */
  312. P2INP &= ~BV(5); /* Pullup all P0 inputs. */
  313. /* Falling edge on P0 pins triggers interrupt. */
  314. PICTL |= BV(0); /* P0ICON */
  315. /* Trigger an interrupt on MRDY input. */
  316. P0IFG &= ~NP_RDYIn_BIT;
  317. P0IEN |= NP_RDYIn_BIT;
  318. P0IE = 1;
  319. dmaInit();
  320. U1CSR |= CSR_RE;
  321. }
  322. #endif
  323. /**************************************************************************************************
  324. * @fn npSpiMonitor
  325. *
  326. * @brief This function monitors the SPI signals for error conditions and for the end of a
  327. * transaction. If an error is detected it attempts to recover.
  328. *
  329. * input parameters
  330. *
  331. * None.
  332. *
  333. * output parameters
  334. *
  335. * None.
  336. *
  337. * @return None.
  338. **************************************************************************************************
  339. */
  340. void npSpiMonitor(void)
  341. {
  342. if (ZNP_CFG1_UART == znpCfg1)
  343. {
  344. return;
  345. }
  346. #if ZNP_RUN_WDOG
  347. if ((devState != DEV_HOLD) && (npSpiState == NP_SPI_IDLE))
  348. {
  349. // Enable the watchdog for 1 second period and pet it.
  350. WatchDogEnable( WDTIMX );
  351. }
  352. #endif
  353. switch (npSpiState)
  354. {
  355. case NP_SPI_IDLE:
  356. NP_SPI_ASSERT((P1IFG & NP_RDYIn_BIT) == 0);
  357. break;
  358. #if defined POWER_SAVING
  359. case NP_SPI_MRDY:
  360. npSpiState = NP_SPI_WAIT_RX;
  361. DMA_RX();
  362. NP_RDYOut = 0;
  363. break;
  364. #endif
  365. case NP_SPI_WAIT_RX:
  366. NP_SPI_ASSERT((HAL_DMA_CHECK_IRQ(HAL_DMA_CH_RX)) == 0);
  367. break;
  368. case NP_SPI_WAIT_TX:
  369. NP_SPI_ASSERT((HAL_DMA_CHECK_IRQ(HAL_DMA_CH_TX)) == 0);
  370. break;
  371. case NP_SPI_WAIT_AREQ:
  372. break;
  373. default:
  374. NP_SPI_ASSERT(0);
  375. break;
  376. }
  377. if (npSpiState == NP_SPI_IDLE)
  378. {
  379. *((uint8 *)DMA_UDBUF) = 0; // Clear the SPI Tx buffer to zero.
  380. /* Poll for MRDY in case it was set before slave had setup the ISR.
  381. * Also, async responses may get queued, so flush them out here.
  382. */
  383. if ((NP_RDYIn == 0) || (npSpiReadyCallback()))
  384. {
  385. npSpiAReqReady();
  386. }
  387. }
  388. else
  389. {
  390. halIntState_t his;
  391. HAL_ENTER_CRITICAL_SECTION(his);
  392. if (((npSpiState == NP_SPI_WAIT_RX) &&
  393. (!HAL_DMA_CH_ARMED(HAL_DMA_CH_RX) && !HAL_DMA_CHECK_IRQ(HAL_DMA_CH_RX)))
  394. || ((npSpiState == NP_SPI_WAIT_TX) &&
  395. (!HAL_DMA_CH_ARMED(HAL_DMA_CH_TX) && !HAL_DMA_CHECK_IRQ(HAL_DMA_CH_TX))))
  396. {
  397. HAL_EXIT_CRITICAL_SECTION(his);
  398. if (npSpiState == NP_SPI_WAIT_RX)
  399. {
  400. npSpiRxIsr();
  401. }
  402. else // if (npSpiState == NP_SPI_WAIT_TX)
  403. {
  404. npSpiTxIsr();
  405. }
  406. }
  407. else
  408. {
  409. HAL_EXIT_CRITICAL_SECTION(his);
  410. }
  411. }
  412. #if defined POWER_SAVING
  413. /* A simple ZAP application sending a unicast at 2-Hz was seen to bog down to < 1-Hz OTA unicast
  414. * when the ZNP was configured to be a ZED (i.e. POWER_SAVING was enabled). So adding this delay
  415. * of only 10 msecs before re-enabling CONSERVE showed that the problem was fixed while still
  416. * allowing the ZNP to enter sleep.
  417. */
  418. static uint8 znpSpiActiveShdw;
  419. if (ZG_DEVICE_ENDDEVICE_TYPE && (npSpiState == NP_SPI_IDLE))
  420. {
  421. if (znpSpiActiveShdw)
  422. {
  423. uint8 rxOnIdle;
  424. (void)ZMacGetReq(ZMacRxOnIdle, &rxOnIdle);
  425. if (!rxOnIdle)
  426. {
  427. znpSpiActiveShdw = FALSE;
  428. if (ZSuccess != osal_start_timerEx(znpTaskId, ZNP_PWRMGR_CONSERVE_EVENT,
  429. ZNP_PWRMGR_CONSERVE_DELAY))
  430. {
  431. (void)osal_set_event(znpTaskId, ZNP_PWRMGR_CONSERVE_EVENT);
  432. }
  433. }
  434. }
  435. }
  436. else if (!znpSpiActiveShdw)
  437. {
  438. znpSpiActiveShdw = TRUE;
  439. (void)osal_stop_timerEx(znpTaskId, ZNP_PWRMGR_CONSERVE_EVENT);
  440. (void)osal_clear_event(znpTaskId, ZNP_PWRMGR_CONSERVE_EVENT);
  441. (void)osal_pwrmgr_task_state(znpTaskId, PWRMGR_HOLD);
  442. }
  443. #endif
  444. }
  445. /**************************************************************************************************
  446. * @fn npSpiSRspAlloc
  447. *
  448. * @brief This function is called by MT to allocate a buffer in which to build an SRSP frame.
  449. * MT must only call this function after processing a received SREQ frame.
  450. *
  451. * input parameters
  452. *
  453. * @param len - Length of the buffer required.
  454. *
  455. * output parameters
  456. *
  457. * None.
  458. *
  459. * @return NULL for failure; a pointer to the npSpiBuf on success. Success is determined by
  460. * the correct npSpiState and H/W signals as well as a valid length request.
  461. **************************************************************************************************
  462. */
  463. uint8 *npSpiSRspAlloc(uint8 len)
  464. {
  465. if (npSpiState == NP_SPI_WAIT_SREQ)
  466. {
  467. return npSpiBuf;
  468. }
  469. else
  470. {
  471. return NULL;
  472. }
  473. }
  474. /**************************************************************************************************
  475. * @fn npSpiAReqAlloc
  476. *
  477. * @brief This function is called by MT to allocate a buffer in which to buld an AREQ frame.
  478. *
  479. * input parameters
  480. *
  481. * @param len - Length of the buffer required.
  482. *
  483. * output parameters
  484. *
  485. * None.
  486. *
  487. * @return NULL for failure; otherwise a pointer to the data of an osal message.
  488. **************************************************************************************************
  489. */
  490. uint8 *npSpiAReqAlloc(uint8 len)
  491. {
  492. return osal_msg_allocate(len + MT_RPC_FRAME_HDR_SZ);
  493. }
  494. /**************************************************************************************************
  495. * @fn npSpiSRspReady
  496. *
  497. * @brief This function is called by MT to notify SPI driver that an SRSP is ready to Tx.
  498. *
  499. * input parameters
  500. *
  501. * @param pBuf - Pointer to the buffer to transmit on the SPI.
  502. *
  503. * output parameters
  504. *
  505. * None.
  506. *
  507. * @return None.
  508. **************************************************************************************************
  509. */
  510. void npSpiSRspReady(uint8 *pBuf)
  511. {
  512. if ((npSpiState == NP_SPI_WAIT_SREQ) && (NP_RDYOut == 0))
  513. {
  514. npSpiState = NP_SPI_WAIT_TX;
  515. DMA_TX( pBuf );
  516. NP_RDYOut = 1;
  517. }
  518. }
  519. /**************************************************************************************************
  520. * @fn npSpiAReqReady
  521. *
  522. * @brief This function is called by MT to notify the SPI driver that an AREQ frame is ready
  523. * to be transmitted.
  524. *
  525. * input parameters
  526. *
  527. * None.
  528. *
  529. * output parameters
  530. *
  531. * None.
  532. *
  533. * @return None.
  534. **************************************************************************************************
  535. */
  536. void npSpiAReqReady(void)
  537. {
  538. halIntState_t intState;
  539. HAL_ENTER_CRITICAL_SECTION(intState);
  540. if (npSpiState == NP_SPI_IDLE)
  541. {
  542. npSpiState = NP_SPI_WAIT_RX;
  543. DMA_RX();
  544. NP_RDYOut = 0;
  545. }
  546. HAL_EXIT_CRITICAL_SECTION(intState);
  547. }
  548. /**************************************************************************************************
  549. * @fn npSpiAReqComplete
  550. *
  551. * @brief This function is called by MT to notify the SPI driver that the processing of a
  552. * received AREQ is complete.
  553. *
  554. * input parameters
  555. *
  556. * None.
  557. *
  558. * output parameters
  559. *
  560. * None.
  561. *
  562. * @return None.
  563. **************************************************************************************************
  564. */
  565. void npSpiAReqComplete(void)
  566. {
  567. if (npSpiState == NP_SPI_WAIT_AREQ)
  568. {
  569. npSpiState = NP_SPI_IDLE;
  570. }
  571. }
  572. /**************************************************************************************************
  573. * @fn npSpiGetReqBuf
  574. *
  575. * @brief This function is called by the application to get the buffer containing the
  576. * currently received AREQ or SREQ.
  577. *
  578. * input parameters
  579. *
  580. * None.
  581. *
  582. * output parameters
  583. *
  584. * None.
  585. *
  586. * @return Pointer to the buffer containing the currently received AREQ or SREQ.
  587. **************************************************************************************************
  588. */
  589. uint8 *npSpiGetReqBuf(void)
  590. {
  591. if (npSpiState != NP_SPI_IDLE)
  592. {
  593. return npSpiBuf;
  594. }
  595. else
  596. {
  597. return NULL;
  598. }
  599. }
  600. /**************************************************************************************************
  601. * @fn npSpiMrdyIsr
  602. *
  603. * @brief This function is called when a GPIO falling-edge interrupt occurs on the MRDY.
  604. *
  605. * input parameters
  606. *
  607. * None.
  608. *
  609. * output parameters
  610. *
  611. * None.
  612. *
  613. * @return None.
  614. **************************************************************************************************
  615. */
  616. void npSpiMrdyIsr(void)
  617. {
  618. if (npSpiState == NP_SPI_IDLE)
  619. {
  620. #if defined POWER_SAVING
  621. if (ZG_DEVICE_ENDDEVICE_TYPE)
  622. {
  623. npSpiState = NP_SPI_MRDY;
  624. }
  625. else
  626. #endif
  627. {
  628. npSpiState = NP_SPI_WAIT_RX;
  629. DMA_RX();
  630. NP_RDYOut = 0;
  631. }
  632. }
  633. }
  634. /**************************************************************************************************
  635. * @fn npSpiRxIsr
  636. *
  637. * @brief This function handles the DMA Rx complete interrupt.
  638. *
  639. * input parameters
  640. *
  641. * None.
  642. *
  643. * output parameters
  644. *
  645. * None.
  646. *
  647. * @return None.
  648. **************************************************************************************************
  649. */
  650. void npSpiRxIsr(void)
  651. {
  652. mtRpcCmdType_t type = (mtRpcCmdType_t)(npSpiBuf[1] & MT_RPC_CMD_TYPE_MASK);
  653. uint8 *pBuf, rdy = 1;
  654. NP_SPI_ASSERT(npSpiState == NP_SPI_WAIT_RX);
  655. switch (type)
  656. {
  657. case MT_RPC_CMD_POLL:
  658. if ( (pBuf = npSpiPollCallback()) == NULL )
  659. {
  660. pBuf = npSpiBuf;
  661. npSpiBuf[0] = 0;
  662. npSpiBuf[1] = 0;
  663. npSpiBuf[2] = 0;
  664. }
  665. npSpiState = NP_SPI_WAIT_TX;
  666. DMA_TX(pBuf);
  667. break;
  668. case MT_RPC_CMD_SREQ:
  669. npSpiState = NP_SPI_WAIT_SREQ;
  670. osal_set_event(znpTaskId, ZNP_SPI_RX_SREQ_EVENT);
  671. rdy = 0;
  672. break;
  673. case MT_RPC_CMD_AREQ:
  674. npSpiState = NP_SPI_WAIT_AREQ;
  675. osal_set_event(znpTaskId, ZNP_SPI_RX_AREQ_EVENT);
  676. break;
  677. default:
  678. npSpiState = NP_SPI_IDLE;
  679. break;
  680. }
  681. NP_RDYOut = rdy;
  682. }
  683. /**************************************************************************************************
  684. * @fn npSpiTxIsr
  685. *
  686. * @brief This function handles the DMA Tx complete interrupt.
  687. *
  688. * input parameters
  689. *
  690. * None.
  691. *
  692. * output parameters
  693. *
  694. * None.
  695. *
  696. * @return None.
  697. **************************************************************************************************
  698. */
  699. void npSpiTxIsr(void)
  700. {
  701. halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX);
  702. uint16 src;
  703. NP_SPI_ASSERT(npSpiState == NP_SPI_WAIT_TX);
  704. HAL_DMA_GET_SOURCE( ch, src );
  705. if ((uint8 *)src != npSpiBuf)
  706. {
  707. osal_msg_deallocate((uint8 *)src);
  708. }
  709. npSpiState = NP_SPI_IDLE;
  710. }
  711. /**************************************************************************************************
  712. * @fn npSpiIdle
  713. *
  714. * @brief This function returns true if SPI is idle and there is no queued data.
  715. *
  716. * input parameters
  717. *
  718. * None.
  719. *
  720. * output parameters
  721. *
  722. * None.
  723. *
  724. * @return True if SPI is idle with no quequed data.
  725. **************************************************************************************************
  726. */
  727. bool npSpiIdle(void)
  728. {
  729. return (npSpiState == NP_SPI_IDLE && !npSpiReadyCallback());
  730. }
  731. /**************************************************************************************************
  732. * @fn portN-Isr
  733. *
  734. * @brief This function handles the PORT-N interrupt.
  735. *
  736. * input parameters
  737. *
  738. * None.
  739. *
  740. * output parameters
  741. *
  742. * None.
  743. *
  744. * @return None.
  745. **************************************************************************************************
  746. */
  747. #if defined CC2530_MK
  748. HAL_ISR_FUNCTION(port2Isr, P2INT_VECTOR)
  749. {
  750. P2IFG = 0;
  751. P2IF = 0;
  752. #else
  753. HAL_ISR_FUNCTION(port0Isr, P0INT_VECTOR)
  754. {
  755. P0IFG = 0;
  756. P0IF = 0;
  757. #endif
  758. // Knowing which pin requires a #define from _hal_uart_dma.c
  759. //if (P0IFG & NP_RDYIn_BIT)
  760. {
  761. if (ZNP_CFG1_UART == znpCfg1)
  762. {
  763. osal_set_event(znpTaskId, ZNP_UART_TX_READY_EVENT);
  764. }
  765. else
  766. {
  767. npSpiMrdyIsr();
  768. }
  769. }
  770. }
  771. /**************************************************************************************************
  772. */