_hal_uart_isr.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. /**************************************************************************************************
  2. Filename: _hal_uart_isr.c
  3. Revised: $Date: 2009-03-12 16:25:22 -0700 (Thu, 12 Mar 2009) $
  4. Revision: $Revision: 19404 $
  5. Description: This file contains the interface to the H/W UART driver by ISR.
  6. Copyright 2006-2009 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. #include "osal.h"
  46. /*********************************************************************
  47. * MACROS
  48. */
  49. //#define HAL_UART_ASSERT(expr) HAL_ASSERT((expr))
  50. #define HAL_UART_ASSERT(expr)
  51. #define HAL_UART_ISR_RX_AVAIL() \
  52. (isrCfg.rxTail >= isrCfg.rxHead) ? \
  53. (isrCfg.rxTail - isrCfg.rxHead) : \
  54. (HAL_UART_ISR_RX_MAX - isrCfg.rxHead + isrCfg.rxTail)
  55. #define HAL_UART_ISR_TX_AVAIL() \
  56. (isrCfg.txHead > isrCfg.txTail) ? \
  57. (isrCfg.txHead - isrCfg.txTail - 1) : \
  58. (HAL_UART_ISR_TX_MAX - isrCfg.txTail + isrCfg.txHead - 1)
  59. /*********************************************************************
  60. * CONSTANTS
  61. */
  62. // UxCSR - USART Control and Status Register.
  63. #define CSR_MODE 0x80
  64. #define CSR_RE 0x40
  65. #define CSR_SLAVE 0x20
  66. #define CSR_FE 0x10
  67. #define CSR_ERR 0x08
  68. #define CSR_RX_BYTE 0x04
  69. #define CSR_TX_BYTE 0x02
  70. #define CSR_ACTIVE 0x01
  71. // UxUCR - USART UART Control Register.
  72. #define UCR_FLUSH 0x80
  73. #define UCR_FLOW 0x40
  74. #define UCR_D9 0x20
  75. #define UCR_BIT9 0x10
  76. #define UCR_PARITY 0x08
  77. #define UCR_SPB 0x04
  78. #define UCR_STOP 0x02
  79. #define UCR_START 0x01
  80. #define UTX0IE 0x04
  81. #define UTX1IE 0x08
  82. #define P2DIR_PRIPO 0xC0
  83. // Incompatible redefinitions between the 2 UART driver sub-modules:
  84. #undef PxSEL
  85. #undef UxCSR
  86. #undef UxUCR
  87. #undef UxDBUF
  88. #undef UxBAUD
  89. #undef UxGCR
  90. #undef URXxIE
  91. #undef UTXxIE
  92. #undef UTXxIF
  93. #if (HAL_UART_ISR == 1)
  94. #define PxOUT P0
  95. #define PxDIR P0DIR
  96. #define PxSEL P0SEL
  97. #define UxCSR U0CSR
  98. #define UxUCR U0UCR
  99. #define UxDBUF U0DBUF
  100. #define UxBAUD U0BAUD
  101. #define UxGCR U0GCR
  102. #define URXxIE URX0IE
  103. #define UTXxIE UTX0IE
  104. #define UTXxIF UTX0IF
  105. #define UxRX_TX 0x0C
  106. #define HAL_UART_PERCFG_BIT 0x01
  107. #define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.
  108. #define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.
  109. #else
  110. #define PxOUT P1
  111. #define PxDIR P1DIR
  112. #define PxSEL P1SEL
  113. #define UxCSR U1CSR
  114. #define UxUCR U1UCR
  115. #define UxDBUF U1DBUF
  116. #define UxBAUD U1BAUD
  117. #define UxGCR U1GCR
  118. #define URXxIE URX1IE
  119. #define UTXxIE UTX1IE
  120. #define UTXxIF UTX1IF
  121. #define UxRX_TX 0xC0
  122. #define HAL_UART_PERCFG_BIT 0x02
  123. #define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.
  124. #define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.
  125. #endif
  126. // The timeout tick is at 32-kHz, so multiply msecs by 33.
  127. #define HAL_UART_MSECS_TO_TICKS 33
  128. #if defined MT_TASK
  129. #define HAL_UART_ISR_TX_MAX MT_UART_DEFAULT_MAX_TX_BUFF
  130. #define HAL_UART_ISR_RX_MAX MT_UART_DEFAULT_MAX_RX_BUFF
  131. #define HAL_UART_ISR_HIGH MT_UART_DEFAULT_THRESHOLD
  132. #define HAL_UART_ISR_IDLE (MT_UART_DEFAULT_IDLE_TIMEOUT * HAL_UART_MSECS_TO_TICKS)
  133. #else
  134. #if !defined HAL_UART_ISR_RX_MAX
  135. #define HAL_UART_ISR_RX_MAX 128
  136. #endif
  137. #if !defined HAL_UART_ISR_TX_MAX
  138. #define HAL_UART_ISR_TX_MAX HAL_UART_ISR_RX_MAX
  139. #endif
  140. #if !defined HAL_UART_ISR_HIGH
  141. #define HAL_UART_ISR_HIGH (HAL_UART_ISR_RX_MAX / 2 - 16)
  142. #endif
  143. #if !defined HAL_UART_ISR_IDLE
  144. #define HAL_UART_ISR_IDLE (6 * HAL_UART_MSECS_TO_TICKS)
  145. #endif
  146. #endif
  147. /*********************************************************************
  148. * TYPEDEFS
  149. */
  150. typedef struct
  151. {
  152. uint8 rxBuf[HAL_UART_ISR_RX_MAX];
  153. #if HAL_UART_ISR_RX_MAX < 256
  154. uint8 rxHead;
  155. volatile uint8 rxTail;
  156. #else
  157. uint16 rxHead;
  158. volatile uint16 rxTail;
  159. #endif
  160. uint8 rxTick;
  161. uint8 rxShdw;
  162. uint8 txBuf[HAL_UART_ISR_TX_MAX];
  163. #if HAL_UART_ISR_TX_MAX < 256
  164. volatile uint8 txHead;
  165. uint8 txTail;
  166. #else
  167. volatile uint16 txHead;
  168. uint16 txTail;
  169. #endif
  170. uint8 txMT;
  171. halUARTCBack_t uartCB;
  172. } uartISRCfg_t;
  173. /*********************************************************************
  174. * GLOBAL VARIABLES
  175. */
  176. /*********************************************************************
  177. * GLOBAL FUNCTIONS
  178. */
  179. /*********************************************************************
  180. * LOCAL VARIABLES
  181. */
  182. static uartISRCfg_t isrCfg;
  183. /*********************************************************************
  184. * LOCAL FUNCTIONS
  185. */
  186. static void HalUARTInitISR(void);
  187. static void HalUARTOpenISR(halUARTCfg_t *config);
  188. static uint16 HalUARTReadISR(uint8 *buf, uint16 len);
  189. static uint16 HalUARTWriteISR(uint8 *buf, uint16 len);
  190. static void HalUARTPollISR(void);
  191. static uint16 HalUARTRxAvailISR(void);
  192. static void HalUARTSuspendISR(void);
  193. static void HalUARTResumeISR(void);
  194. /******************************************************************************
  195. * @fn HalUARTInitISR
  196. *
  197. * @brief Initialize the UART
  198. *
  199. * @param none
  200. *
  201. * @return none
  202. *****************************************************************************/
  203. static void HalUARTInitISR(void)
  204. {
  205. // Set P2 priority - USART0 over USART1 if both are defined.
  206. P2DIR &= ~P2DIR_PRIPO;
  207. P2DIR |= HAL_UART_PRIPO;
  208. #if (HAL_UART_ISR == 1)
  209. PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O location to P0.
  210. #else
  211. PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O location to P1.
  212. #endif
  213. PxSEL |= UxRX_TX; // Enable Tx and Rx peripheral functions on pins.
  214. ADCCFG &= ~UxRX_TX; // Make sure ADC doesnt use this.
  215. UxCSR = CSR_MODE; // Mode is UART Mode.
  216. UxUCR = UCR_FLUSH; // Flush it.
  217. }
  218. /******************************************************************************
  219. * @fn HalUARTOpenISR
  220. *
  221. * @brief Open a port according tp the configuration specified by parameter.
  222. *
  223. * @param config - contains configuration information
  224. *
  225. * @return none
  226. *****************************************************************************/
  227. static void HalUARTOpenISR(halUARTCfg_t *config)
  228. {
  229. isrCfg.uartCB = config->callBackFunc;
  230. // Only supporting subset of baudrate for code size - other is possible.
  231. HAL_UART_ASSERT((config->baudRate == HAL_UART_BR_9600) ||
  232. (config->baudRate == HAL_UART_BR_19200) ||
  233. (config->baudRate == HAL_UART_BR_38400) ||
  234. (config->baudRate == HAL_UART_BR_57600) ||
  235. (config->baudRate == HAL_UART_BR_115200));
  236. if (config->baudRate == HAL_UART_BR_57600 ||
  237. config->baudRate == HAL_UART_BR_115200)
  238. {
  239. UxBAUD = 216;
  240. }
  241. else
  242. {
  243. UxBAUD = 59;
  244. }
  245. switch (config->baudRate)
  246. {
  247. case HAL_UART_BR_9600:
  248. UxGCR = 8;
  249. break;
  250. case HAL_UART_BR_19200:
  251. UxGCR = 9;
  252. break;
  253. case HAL_UART_BR_38400:
  254. case HAL_UART_BR_57600:
  255. UxGCR = 10;
  256. break;
  257. default:
  258. UxGCR = 11;
  259. break;
  260. }
  261. // 8 bits/char; no parity; 1 stop bit; stop bit hi.
  262. if (config->flowControl)
  263. {
  264. UxUCR = UCR_FLOW | UCR_STOP;
  265. PxSEL |= HAL_UART_Px_RTS | HAL_UART_Px_CTS;
  266. }
  267. else
  268. {
  269. UxUCR = UCR_STOP;
  270. }
  271. UxCSR |= CSR_RE;
  272. URXxIE = 1;
  273. UxDBUF = 0; // Prime the ISR pump.
  274. }
  275. /*****************************************************************************
  276. * @fn HalUARTReadISR
  277. *
  278. * @brief Read a buffer from the UART
  279. *
  280. * @param buf - valid data buffer at least 'len' bytes in size
  281. * len - max length number of bytes to copy to 'buf'
  282. *
  283. * @return length of buffer that was read
  284. *****************************************************************************/
  285. static uint16 HalUARTReadISR(uint8 *buf, uint16 len)
  286. {
  287. uint16 cnt = 0;
  288. while ((isrCfg.rxHead != isrCfg.rxTail) && (cnt < len))
  289. {
  290. *buf++ = isrCfg.rxBuf[isrCfg.rxHead++];
  291. if (isrCfg.rxHead >= HAL_UART_ISR_RX_MAX)
  292. {
  293. isrCfg.rxHead = 0;
  294. }
  295. cnt++;
  296. }
  297. return cnt;
  298. }
  299. /******************************************************************************
  300. * @fn HalUARTWriteISR
  301. *
  302. * @brief Write a buffer to the UART.
  303. *
  304. * @param buf - pointer to the buffer that will be written, not freed
  305. * len - length of
  306. *
  307. * @return length of the buffer that was sent
  308. *****************************************************************************/
  309. static uint16 HalUARTWriteISR(uint8 *buf, uint16 len)
  310. {
  311. uint16 cnt;
  312. // Accept "all-or-none" on write request.
  313. if (HAL_UART_ISR_TX_AVAIL() < len)
  314. {
  315. return 0;
  316. }
  317. for (cnt = 0; cnt < len; cnt++)
  318. {
  319. isrCfg.txBuf[isrCfg.txTail] = *buf++;
  320. isrCfg.txMT = 0;
  321. if (isrCfg.txTail >= HAL_UART_ISR_TX_MAX-1)
  322. {
  323. isrCfg.txTail = 0;
  324. }
  325. else
  326. {
  327. isrCfg.txTail++;
  328. }
  329. // Keep re-enabling ISR as it might be keeping up with this loop due to other ints.
  330. IEN2 |= UTXxIE;
  331. }
  332. return cnt;
  333. }
  334. /******************************************************************************
  335. * @fn HalUARTPollISR
  336. *
  337. * @brief Poll a USART module implemented by ISR.
  338. *
  339. * @param none
  340. *
  341. * @return none
  342. *****************************************************************************/
  343. static void HalUARTPollISR(void)
  344. {
  345. if (isrCfg.uartCB != NULL)
  346. {
  347. uint16 cnt = HAL_UART_ISR_RX_AVAIL();
  348. uint8 evt = 0;
  349. if (isrCfg.rxTick)
  350. {
  351. // Use the LSB of the sleep timer (ST0 must be read first anyway).
  352. uint8 decr = ST0 - isrCfg.rxShdw;
  353. if (isrCfg.rxTick > decr)
  354. {
  355. isrCfg.rxTick -= decr;
  356. }
  357. else
  358. {
  359. isrCfg.rxTick = 0;
  360. }
  361. }
  362. isrCfg.rxShdw = ST0;
  363. if (cnt >= HAL_UART_ISR_RX_MAX-1)
  364. {
  365. evt = HAL_UART_RX_FULL;
  366. }
  367. else if (cnt >= HAL_UART_ISR_HIGH)
  368. {
  369. evt = HAL_UART_RX_ABOUT_FULL;
  370. }
  371. else if (cnt && !isrCfg.rxTick)
  372. {
  373. evt = HAL_UART_RX_TIMEOUT;
  374. }
  375. if (isrCfg.txMT)
  376. {
  377. isrCfg.txMT = 0;
  378. evt |= HAL_UART_TX_EMPTY;
  379. }
  380. if (evt)
  381. {
  382. isrCfg.uartCB(HAL_UART_ISR-1, evt);
  383. }
  384. }
  385. }
  386. /**************************************************************************************************
  387. * @fn HalUARTRxAvailISR()
  388. *
  389. * @brief Calculate Rx Buffer length - the number of bytes in the buffer.
  390. *
  391. * @param none
  392. *
  393. * @return length of current Rx Buffer
  394. **************************************************************************************************/
  395. static uint16 HalUARTRxAvailISR(void)
  396. {
  397. return HAL_UART_ISR_RX_AVAIL();
  398. }
  399. /******************************************************************************
  400. * @fn HalUARTSuspendISR
  401. *
  402. * @brief Suspend UART hardware before entering PM mode 1, 2 or 3.
  403. *
  404. * @param None
  405. *
  406. * @return None
  407. *****************************************************************************/
  408. static void HalUARTSuspendISR( void )
  409. {
  410. UxCSR &= ~CSR_RE;
  411. }
  412. /******************************************************************************
  413. * @fn HalUARTResumeISR
  414. *
  415. * @brief Resume UART hardware after exiting PM mode 1, 2 or 3.
  416. *
  417. * @param None
  418. *
  419. * @return None
  420. *****************************************************************************/
  421. static void HalUARTResumeISR( void )
  422. {
  423. UxUCR |= UCR_FLUSH;
  424. UxCSR |= CSR_RE;
  425. }
  426. /***************************************************************************************************
  427. * @fn halUartRxIsr
  428. *
  429. * @brief UART Receive Interrupt
  430. *
  431. * @param None
  432. *
  433. * @return None
  434. ***************************************************************************************************/
  435. #if (HAL_UART_ISR == 1)
  436. HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )
  437. #else
  438. HAL_ISR_FUNCTION( halUart1RxIsr, URX1_VECTOR )
  439. #endif
  440. {
  441. uint8 tmp = UxDBUF;
  442. isrCfg.rxBuf[isrCfg.rxTail] = tmp;
  443. // Re-sync the shadow on any 1st byte received.
  444. if (isrCfg.rxHead == isrCfg.rxTail)
  445. {
  446. isrCfg.rxShdw = ST0;
  447. }
  448. if (++isrCfg.rxTail >= HAL_UART_ISR_RX_MAX)
  449. {
  450. isrCfg.rxTail = 0;
  451. }
  452. isrCfg.rxTick = HAL_UART_ISR_IDLE;
  453. }
  454. /***************************************************************************************************
  455. * @fn halUartTxIsr
  456. *
  457. * @brief UART Transmit Interrupt
  458. *
  459. * @param None
  460. *
  461. * @return None
  462. ***************************************************************************************************/
  463. #if (HAL_UART_ISR == 1)
  464. HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR )
  465. #else
  466. HAL_ISR_FUNCTION( halUart1TxIsr, UTX1_VECTOR )
  467. #endif
  468. {
  469. if (isrCfg.txHead == isrCfg.txTail)
  470. {
  471. IEN2 &= ~UTXxIE;
  472. isrCfg.txMT = 1;
  473. }
  474. else
  475. {
  476. UTXxIF = 0;
  477. UxDBUF = isrCfg.txBuf[isrCfg.txHead++];
  478. if (isrCfg.txHead >= HAL_UART_ISR_TX_MAX)
  479. {
  480. isrCfg.txHead = 0;
  481. }
  482. }
  483. }
  484. /******************************************************************************
  485. ******************************************************************************/