_hal_uart_isr.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. /**************************************************************************************************
  2. Filename: _hal_uart_isr.c
  3. Revised: $Date: 2012-03-27 14:53:26 -0700 (Tue, 27 Mar 2012) $
  4. Revision: $Revision: 29910 $
  5. Description: This file contains the interface to the H/W UART driver by ISR.
  6. Copyright 2006-2012 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. **************************************************************************************************/
  33. /*********************************************************************
  34. * INCLUDES
  35. */
  36. #include "hal_types.h"
  37. #include "hal_assert.h"
  38. #include "hal_board.h"
  39. #include "hal_defs.h"
  40. #include "hal_mcu.h"
  41. #include "hal_uart.h"
  42. #if defined MT_TASK
  43. #include "MT_UART.h"
  44. #endif
  45. /*********************************************************************
  46. * MACROS
  47. */
  48. //#define HAL_UART_ASSERT(expr) HAL_ASSERT((expr))
  49. #define HAL_UART_ASSERT(expr)
  50. #define HAL_UART_ISR_RX_AVAIL() \
  51. (isrCfg.rxTail >= isrCfg.rxHead) ? \
  52. (isrCfg.rxTail - isrCfg.rxHead) : \
  53. (HAL_UART_ISR_RX_MAX - isrCfg.rxHead + isrCfg.rxTail)
  54. #define HAL_UART_ISR_TX_AVAIL() \
  55. (isrCfg.txHead > isrCfg.txTail) ? \
  56. (isrCfg.txHead - isrCfg.txTail - 1) : \
  57. (HAL_UART_ISR_TX_MAX - isrCfg.txTail + isrCfg.txHead - 1)
  58. /*********************************************************************
  59. * CONSTANTS
  60. */
  61. // UxCSR - USART Control and Status Register.
  62. #define CSR_MODE 0x80
  63. #define CSR_RE 0x40
  64. #define CSR_SLAVE 0x20
  65. #define CSR_FE 0x10
  66. #define CSR_ERR 0x08
  67. #define CSR_RX_BYTE 0x04
  68. #define CSR_TX_BYTE 0x02
  69. #define CSR_ACTIVE 0x01
  70. // UxUCR - USART UART Control Register.
  71. #define UCR_FLUSH 0x80
  72. #define UCR_FLOW 0x40
  73. #define UCR_D9 0x20
  74. #define UCR_BIT9 0x10
  75. #define UCR_PARITY 0x08
  76. #define UCR_SPB 0x04
  77. #define UCR_STOP 0x02
  78. #define UCR_START 0x01
  79. #define UTX0IE 0x04
  80. #define UTX1IE 0x08
  81. #define P2DIR_PRIPO 0xC0
  82. // Incompatible redefinitions result with more than one UART driver sub-module.
  83. #undef PxOUT
  84. #undef PxDIR
  85. #undef PxSEL
  86. #undef UxCSR
  87. #undef UxUCR
  88. #undef UxDBUF
  89. #undef UxBAUD
  90. #undef UxGCR
  91. #undef URXxIE
  92. #undef URXxIF
  93. #undef UTXxIE
  94. #undef UTXxIF
  95. #undef HAL_UART_PERCFG_BIT
  96. #undef HAL_UART_Px_RTS
  97. #undef HAL_UART_Px_CTS
  98. #undef HAL_UART_Px_RX_TX
  99. #if (HAL_UART_ISR == 1)
  100. #define PxOUT P0
  101. #define PxDIR P0DIR
  102. #define PxSEL P0SEL
  103. #define UxCSR U0CSR
  104. #define UxUCR U0UCR
  105. #define UxDBUF U0DBUF
  106. #define UxBAUD U0BAUD
  107. #define UxGCR U0GCR
  108. #define URXxIE URX0IE
  109. #define URXxIF URX0IF
  110. #define UTXxIE UTX0IE
  111. #define UTXxIF UTX0IF
  112. #else
  113. #define PxOUT P1
  114. #define PxDIR P1DIR
  115. #define PxSEL P1SEL
  116. #define UxCSR U1CSR
  117. #define UxUCR U1UCR
  118. #define UxDBUF U1DBUF
  119. #define UxBAUD U1BAUD
  120. #define UxGCR U1GCR
  121. #define URXxIE URX1IE
  122. #define URXxIF URX1IF
  123. #define UTXxIE UTX1IE
  124. #define UTXxIF UTX1IF
  125. #endif
  126. #if (HAL_UART_ISR == 1)
  127. #define HAL_UART_PERCFG_BIT 0x01 // USART0 on P0, Alt-1; so clear this bit.
  128. #define HAL_UART_Px_RX_TX 0x0C // Peripheral I/O Select for Rx/Tx.
  129. #define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.
  130. #define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.
  131. #else
  132. #define HAL_UART_PERCFG_BIT 0x02 // USART1 on P1, Alt-2; so set this bit.
  133. #define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.
  134. #define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.
  135. #define HAL_UART_Px_RX_TX 0xC0 // Peripheral I/O Select for Rx/Tx.
  136. #endif
  137. // The timeout tick is at 32-kHz, so multiply msecs by 33.
  138. #define HAL_UART_MSECS_TO_TICKS 33
  139. #if defined MT_TASK
  140. #define HAL_UART_ISR_TX_MAX MT_UART_DEFAULT_MAX_TX_BUFF
  141. #define HAL_UART_ISR_RX_MAX MT_UART_DEFAULT_MAX_RX_BUFF
  142. #define HAL_UART_ISR_HIGH MT_UART_DEFAULT_THRESHOLD
  143. #define HAL_UART_ISR_IDLE (MT_UART_DEFAULT_IDLE_TIMEOUT * HAL_UART_MSECS_TO_TICKS)
  144. #else
  145. #if !defined HAL_UART_ISR_RX_MAX
  146. #define HAL_UART_ISR_RX_MAX 128
  147. #endif
  148. #if !defined HAL_UART_ISR_TX_MAX
  149. #define HAL_UART_ISR_TX_MAX HAL_UART_ISR_RX_MAX
  150. #endif
  151. #if !defined HAL_UART_ISR_HIGH
  152. #define HAL_UART_ISR_HIGH (HAL_UART_ISR_RX_MAX / 2 - 16)
  153. #endif
  154. #if !defined HAL_UART_ISR_IDLE
  155. #define HAL_UART_ISR_IDLE (6 * HAL_UART_MSECS_TO_TICKS)
  156. #endif
  157. #endif
  158. /*********************************************************************
  159. * TYPEDEFS
  160. */
  161. typedef struct
  162. {
  163. uint8 rxBuf[HAL_UART_ISR_RX_MAX];
  164. #if HAL_UART_ISR_RX_MAX < 256
  165. uint8 rxHead;
  166. volatile uint8 rxTail;
  167. #else
  168. uint16 rxHead;
  169. volatile uint16 rxTail;
  170. #endif
  171. uint8 rxTick;
  172. uint8 rxShdw;
  173. uint8 txBuf[HAL_UART_ISR_TX_MAX];
  174. #if HAL_UART_ISR_TX_MAX < 256
  175. volatile uint8 txHead;
  176. uint8 txTail;
  177. #else
  178. volatile uint16 txHead;
  179. uint16 txTail;
  180. #endif
  181. uint8 txMT;
  182. halUARTCBack_t uartCB;
  183. } uartISRCfg_t;
  184. /*********************************************************************
  185. * GLOBAL VARIABLES
  186. */
  187. /*********************************************************************
  188. * GLOBAL FUNCTIONS
  189. */
  190. /*********************************************************************
  191. * LOCAL VARIABLES
  192. */
  193. static uartISRCfg_t isrCfg;
  194. /*********************************************************************
  195. * LOCAL FUNCTIONS
  196. */
  197. static void HalUARTInitISR(void);
  198. static void HalUARTOpenISR(halUARTCfg_t *config);
  199. uint16 HalUARTReadISR(uint8 *buf, uint16 len);
  200. uint16 HalUARTWriteISR(uint8 *buf, uint16 len);
  201. static void HalUARTPollISR(void);
  202. static uint16 HalUARTRxAvailISR(void);
  203. static void HalUARTSuspendISR(void);
  204. static void HalUARTResumeISR(void);
  205. /******************************************************************************
  206. * @fn HalUARTInitISR
  207. *
  208. * @brief Initialize the UART
  209. *
  210. * @param none
  211. *
  212. * @return none
  213. *****************************************************************************/
  214. static void HalUARTInitISR(void)
  215. {
  216. // Set P2 priority - USART0 over USART1 if both are defined.
  217. P2DIR &= ~P2DIR_PRIPO;
  218. P2DIR |= HAL_UART_PRIPO;
  219. #if (HAL_UART_ISR == 1)
  220. PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O location to P0.
  221. #else
  222. PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O location to P1.
  223. #endif
  224. PxSEL |= HAL_UART_Px_RX_TX; // Enable Tx and Rx on P1.
  225. ADCCFG &= ~HAL_UART_Px_RX_TX; // Make sure ADC doesnt use this.
  226. UxCSR = CSR_MODE; // Mode is UART Mode.
  227. UxUCR = UCR_FLUSH; // Flush it.
  228. }
  229. /******************************************************************************
  230. * @fn HalUARTUnInitISR
  231. *
  232. * @brief UnInitialize the UART.
  233. *
  234. * @param none
  235. *
  236. * @return none
  237. *****************************************************************************/
  238. static void HalUARTUnInitISR(void)
  239. {
  240. UxCSR = 0;
  241. URXxIE = 0;
  242. URXxIF = 0;
  243. IEN2 &= ~UTXxIE;
  244. UTXxIF = 0;
  245. }
  246. /******************************************************************************
  247. * @fn HalUARTOpenISR
  248. *
  249. * @brief Open a port according tp the configuration specified by parameter.
  250. *
  251. * @param config - contains configuration information
  252. *
  253. * @return none
  254. *****************************************************************************/
  255. static void HalUARTOpenISR(halUARTCfg_t *config)
  256. {
  257. isrCfg.uartCB = config->callBackFunc;
  258. // Only supporting subset of baudrate for code size - other is possible.
  259. HAL_UART_ASSERT((config->baudRate == HAL_UART_BR_9600) ||
  260. (config->baudRate == HAL_UART_BR_19200) ||
  261. (config->baudRate == HAL_UART_BR_38400) ||
  262. (config->baudRate == HAL_UART_BR_57600) ||
  263. (config->baudRate == HAL_UART_BR_115200));
  264. if (config->baudRate == HAL_UART_BR_57600 ||
  265. config->baudRate == HAL_UART_BR_115200)
  266. {
  267. UxBAUD = 216;
  268. }
  269. else
  270. {
  271. UxBAUD = 59;
  272. }
  273. switch (config->baudRate)
  274. {
  275. case HAL_UART_BR_9600:
  276. UxGCR = 8;
  277. break;
  278. case HAL_UART_BR_19200:
  279. UxGCR = 9;
  280. break;
  281. case HAL_UART_BR_38400:
  282. case HAL_UART_BR_57600:
  283. UxGCR = 10;
  284. break;
  285. default:
  286. UxGCR = 11;
  287. break;
  288. }
  289. // 8 bits/char; no parity; 1 stop bit; stop bit hi.
  290. if (config->flowControl)
  291. {
  292. UxUCR = UCR_FLOW | UCR_STOP;
  293. PxSEL |= HAL_UART_Px_RTS | HAL_UART_Px_CTS;
  294. }
  295. else
  296. {
  297. UxUCR = UCR_STOP;
  298. }
  299. UxCSR |= CSR_RE;
  300. URXxIE = 1;
  301. UTXxIF = 1; // Prime the ISR pump.
  302. }
  303. /*****************************************************************************
  304. * @fn HalUARTReadISR
  305. *
  306. * @brief Read a buffer from the UART
  307. *
  308. * @param buf - valid data buffer at least 'len' bytes in size
  309. * len - max length number of bytes to copy to 'buf'
  310. *
  311. * @return length of buffer that was read
  312. *****************************************************************************/
  313. uint16 HalUARTReadISR(uint8 *buf, uint16 len)
  314. {
  315. uint16 cnt = 0;
  316. while ((isrCfg.rxHead != isrCfg.rxTail) && (cnt < len))
  317. {
  318. *buf++ = isrCfg.rxBuf[isrCfg.rxHead++];
  319. if (isrCfg.rxHead >= HAL_UART_ISR_RX_MAX)
  320. {
  321. isrCfg.rxHead = 0;
  322. }
  323. cnt++;
  324. }
  325. return cnt;
  326. }
  327. /******************************************************************************
  328. * @fn HalUARTWriteISR
  329. *
  330. * @brief Write a buffer to the UART.
  331. *
  332. * @param buf - pointer to the buffer that will be written, not freed
  333. * len - length of
  334. *
  335. * @return length of the buffer that was sent
  336. *****************************************************************************/
  337. uint16 HalUARTWriteISR(uint8 *buf, uint16 len)
  338. {
  339. uint16 cnt;
  340. // Enforce all or none.
  341. if (HAL_UART_ISR_TX_AVAIL() < len)
  342. {
  343. return 0;
  344. }
  345. for (cnt = 0; cnt < len; cnt++)
  346. {
  347. isrCfg.txBuf[isrCfg.txTail] = *buf++;
  348. isrCfg.txMT = 0;
  349. if (isrCfg.txTail >= HAL_UART_ISR_TX_MAX-1)
  350. {
  351. isrCfg.txTail = 0;
  352. }
  353. else
  354. {
  355. isrCfg.txTail++;
  356. }
  357. // Keep re-enabling ISR as it might be keeping up with this loop due to other ints.
  358. IEN2 |= UTXxIE;
  359. }
  360. return cnt;
  361. }
  362. /******************************************************************************
  363. * @fn HalUARTPollISR
  364. *
  365. * @brief Poll a USART module implemented by ISR.
  366. *
  367. * @param none
  368. *
  369. * @return none
  370. *****************************************************************************/
  371. static void HalUARTPollISR(void)
  372. {
  373. if (isrCfg.uartCB != NULL)
  374. {
  375. uint16 cnt = HAL_UART_ISR_RX_AVAIL();
  376. uint8 evt = 0;
  377. if (isrCfg.rxTick)
  378. {
  379. // Use the LSB of the sleep timer (ST0 must be read first anyway).
  380. uint8 decr = ST0 - isrCfg.rxShdw;
  381. if (isrCfg.rxTick > decr)
  382. {
  383. isrCfg.rxTick -= decr;
  384. }
  385. else
  386. {
  387. isrCfg.rxTick = 0;
  388. }
  389. }
  390. isrCfg.rxShdw = ST0;
  391. if (cnt >= HAL_UART_ISR_RX_MAX-1)
  392. {
  393. evt = HAL_UART_RX_FULL;
  394. }
  395. else if (cnt >= HAL_UART_ISR_HIGH)
  396. {
  397. evt = HAL_UART_RX_ABOUT_FULL;
  398. }
  399. else if (cnt && !isrCfg.rxTick)
  400. {
  401. evt = HAL_UART_RX_TIMEOUT;
  402. }
  403. if (isrCfg.txMT)
  404. {
  405. isrCfg.txMT = 0;
  406. evt |= HAL_UART_TX_EMPTY;
  407. }
  408. if (evt)
  409. {
  410. isrCfg.uartCB(HAL_UART_ISR-1, evt);
  411. }
  412. }
  413. }
  414. /**************************************************************************************************
  415. * @fn HalUARTRxAvailISR()
  416. *
  417. * @brief Calculate Rx Buffer length - the number of bytes in the buffer.
  418. *
  419. * @param none
  420. *
  421. * @return length of current Rx Buffer
  422. **************************************************************************************************/
  423. static uint16 HalUARTRxAvailISR(void)
  424. {
  425. return HAL_UART_ISR_RX_AVAIL();
  426. }
  427. /******************************************************************************
  428. * @fn HalUARTSuspendISR
  429. *
  430. * @brief Suspend UART hardware before entering PM mode 1, 2 or 3.
  431. *
  432. * @param None
  433. *
  434. * @return None
  435. *****************************************************************************/
  436. static void HalUARTSuspendISR( void )
  437. {
  438. UxCSR &= ~CSR_RE;
  439. }
  440. /******************************************************************************
  441. * @fn HalUARTResumeISR
  442. *
  443. * @brief Resume UART hardware after exiting PM mode 1, 2 or 3.
  444. *
  445. * @param None
  446. *
  447. * @return None
  448. *****************************************************************************/
  449. static void HalUARTResumeISR( void )
  450. {
  451. UxUCR |= UCR_FLUSH;
  452. UxCSR |= CSR_RE;
  453. }
  454. /***************************************************************************************************
  455. * @fn halUartRxIsr
  456. *
  457. * @brief UART Receive Interrupt
  458. *
  459. * @param None
  460. *
  461. * @return None
  462. ***************************************************************************************************/
  463. #if (HAL_UART_ISR == 1)
  464. HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )
  465. #else
  466. HAL_ISR_FUNCTION( halUart1RxIsr, URX1_VECTOR )
  467. #endif
  468. {
  469. uint8 tmp = UxDBUF;
  470. isrCfg.rxBuf[isrCfg.rxTail] = tmp;
  471. // Re-sync the shadow on any 1st byte received.
  472. if (isrCfg.rxHead == isrCfg.rxTail)
  473. {
  474. isrCfg.rxShdw = ST0;
  475. }
  476. if (++isrCfg.rxTail >= HAL_UART_ISR_RX_MAX)
  477. {
  478. isrCfg.rxTail = 0;
  479. }
  480. isrCfg.rxTick = HAL_UART_ISR_IDLE;
  481. }
  482. /***************************************************************************************************
  483. * @fn halUartTxIsr
  484. *
  485. * @brief UART Transmit Interrupt
  486. *
  487. * @param None
  488. *
  489. * @return None
  490. ***************************************************************************************************/
  491. #if (HAL_UART_ISR == 1)
  492. HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR )
  493. #else
  494. HAL_ISR_FUNCTION( halUart1TxIsr, UTX1_VECTOR )
  495. #endif
  496. {
  497. if (isrCfg.txHead == isrCfg.txTail)
  498. {
  499. IEN2 &= ~UTXxIE;
  500. isrCfg.txMT = 1;
  501. }
  502. else
  503. {
  504. UTXxIF = 0;
  505. UxDBUF = isrCfg.txBuf[isrCfg.txHead++];
  506. if (isrCfg.txHead >= HAL_UART_ISR_TX_MAX)
  507. {
  508. isrCfg.txHead = 0;
  509. }
  510. }
  511. }
  512. /******************************************************************************
  513. ******************************************************************************/