_hal_uart_usb.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /**************************************************************************************************
  2. Filename: _hal_uart_usb.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 USB.
  6. Copyright 2009-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_uart.h"
  37. #if defined MT_TASK
  38. #include "MT_UART.h"
  39. #endif
  40. #include "usb_board_cfg.h"
  41. #include "usb_cdc.h"
  42. #include "usb_cdc_hooks.h"
  43. #include "usb_firmware_library_config.h"
  44. #include "usb_firmware_library_headers.h"
  45. /*********************************************************************
  46. * MACROS
  47. */
  48. #if !defined HAL_UART_BAUD_RATE
  49. #define HAL_UART_BAUD_RATE 115200
  50. #endif
  51. // The timeout tick is at 32-kHz, so multiply msecs by 33.
  52. #define HAL_UART_MSECS_TO_TICKS 33
  53. #if defined MT_TASK
  54. #define HAL_UART_USB_HIGH MT_UART_DEFAULT_THRESHOLD
  55. #define HAL_UART_USB_IDLE (MT_UART_DEFAULT_IDLE_TIMEOUT * HAL_UART_MSECS_TO_TICKS)
  56. #define HAL_UART_USB_RX_MAX MT_UART_DEFAULT_MAX_RX_BUFF
  57. #else
  58. #if !defined HAL_UART_USB_HIGH
  59. #define HAL_UART_USB_HIGH (HAL_UART_USB_RX_MAX / 2 - 16)
  60. #endif
  61. #if !defined HAL_UART_USB_IDLE
  62. #define HAL_UART_USB_IDLE (6 * HAL_UART_MSECS_TO_TICKS)
  63. #endif
  64. #if !defined HAL_UART_USB_RX_MAX
  65. #define HAL_UART_USB_RX_MAX 128
  66. #endif
  67. #endif
  68. // Max USB packet size, per specification; see also usb_cdc_descriptor.s51
  69. #if !defined HAL_UART_USB_TX_MAX
  70. #define HAL_UART_USB_TX_MAX 64
  71. #endif
  72. /***********************************************************************************
  73. * EXTERNAL VARIABLES
  74. */
  75. /***********************************************************************************
  76. * GLOBAL VARIABLES
  77. */
  78. /***********************************************************************************
  79. * LOCAL DATA
  80. */
  81. static uint8 halUartRxH, halUartRxT, halUartRxQ[256];
  82. static uint8 halUartTxH, halUartTxT, halUartTxQ[256];
  83. #if !defined HAL_SB_BOOT_CODE
  84. static uint8 rxTick;
  85. static uint8 rxShdw;
  86. static uint8 txMT;
  87. static halUARTCBack_t uartCB;
  88. #endif
  89. /***********************************************************************************
  90. * LOCAL FUNCTIONS
  91. */
  92. static void HalUARTInitUSB(void);
  93. static void HalUARTPollUSB(void);
  94. static void halUartPollEvt(void);
  95. static void halUartPollRx(void);
  96. static void halUartPollTx(void);
  97. /******************************************************************************
  98. * FUNCTIONS
  99. */
  100. /***********************************************************************************
  101. * @fn usbUartInitUSB
  102. *
  103. * @brief USB UART init function.
  104. * - Set initial line decoding to 8/NONE/1.
  105. * - Initialise the USB Firmware Library and the USB controller.
  106. *
  107. * @param none
  108. *
  109. * @return none
  110. */
  111. void HalUARTInitUSB(void)
  112. {
  113. // Set default line coding.
  114. currentLineCoding.dteRate = HAL_UART_BAUD_RATE;
  115. currentLineCoding.charFormat = CDC_CHAR_FORMAT_1_STOP_BIT;
  116. currentLineCoding.parityType = CDC_PARITY_TYPE_NONE;
  117. currentLineCoding.dataBits = 8;
  118. // Init USB library
  119. usbfwInit();
  120. // Initialize the USB interrupt handler with bit mask containing all processed USBIRQ events
  121. usbirqInit(0xFFFF);
  122. #if defined HAL_SB_BOOT_CODE
  123. HAL_USB_PULLUP_ENABLE(); // Enable pullup on D+.
  124. #else
  125. txMT = TRUE;
  126. #endif
  127. }
  128. /******************************************************************************
  129. * @fn HalUARTUnInitUSB
  130. *
  131. * @brief UnInitialize the USB.
  132. *
  133. * @param none
  134. *
  135. * @return none
  136. *****************************************************************************/
  137. static void HalUARTUnInitUSB(void)
  138. {
  139. P2IEN = 0;
  140. IEN2 = 0;
  141. HAL_USB_PULLUP_DISABLE();
  142. HAL_USB_DISABLE;
  143. }
  144. #if !defined HAL_SB_BOOT_CODE
  145. /******************************************************************************
  146. * @fn HalUARTOpenUSB
  147. *
  148. * @brief Open a port according tp the configuration specified by parameter.
  149. *
  150. * @param config - contains configuration information
  151. *
  152. * @return none
  153. *****************************************************************************/
  154. static void HalUARTOpenUSB(halUARTCfg_t *config)
  155. {
  156. // Synchronize initial value to any value between 0 and 255
  157. halUartRxH = halUartRxT;
  158. uartCB = config->callBackFunc;
  159. (void)config;
  160. HAL_USB_PULLUP_ENABLE(); // Enable pullup on D+.
  161. }
  162. #endif
  163. /***********************************************************************************
  164. * @fn HalUartPollUSB
  165. *
  166. * @brief The USB UART main task function. Should be called from the OSAL main loop.
  167. *
  168. * @param none
  169. *
  170. * @return none
  171. */
  172. void HalUARTPollUSB(void)
  173. {
  174. #if defined HAL_SB_BOOT_CODE
  175. while (USBIF) usbirqHandler();
  176. #endif
  177. halUartPollEvt();
  178. halUartPollRx();
  179. halUartPollTx();
  180. }
  181. uint8 HalUARTRx(uint8 *buf, uint8 max);
  182. uint8 HalUARTRx(uint8 *buf, uint8 max)
  183. {
  184. uint8 cnt = 0;
  185. while ((halUartRxH != halUartRxT) && (cnt < max))
  186. {
  187. *buf++ = halUartRxQ[halUartRxH++];
  188. cnt++;
  189. }
  190. return cnt;
  191. }
  192. void HalUARTTx(uint8 *buf, uint8 cnt);
  193. void HalUARTTx(uint8 *buf, uint8 cnt)
  194. {
  195. while (cnt--)
  196. {
  197. halUartTxQ[halUartTxT++] = *buf++;
  198. }
  199. #if !defined HAL_SB_BOOT_CODE
  200. txMT = FALSE;
  201. #endif
  202. }
  203. /**************************************************************************************************
  204. * @fn HalUARTRxAvailUSB()
  205. *
  206. * @brief Calculate Rx Buffer length - the number of bytes in the buffer.
  207. *
  208. * @param none
  209. *
  210. * @return length of current Rx Buffer
  211. **************************************************************************************************/
  212. static uint16 HalUARTRxAvailUSB(void)
  213. {
  214. return ((halUartRxT >= halUartRxH)?
  215. halUartRxT - halUartRxH : sizeof(halUartRxQ) - halUartRxH + halUartRxT);
  216. }
  217. /***********************************************************************************
  218. * @fn halUartPollEvt
  219. *
  220. * @brief Poll for USB events which are not directly related to the UART.
  221. *
  222. * @param none
  223. *
  224. * @return none
  225. */
  226. static void halUartPollEvt(void)
  227. {
  228. // Handle reset signaling on the bus
  229. if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_RESET)
  230. {
  231. USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESET);
  232. usbfwResetHandler();
  233. }
  234. // Handle packets on EP0
  235. if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SETUP)
  236. {
  237. USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SETUP);
  238. usbfwSetupHandler();
  239. }
  240. // Handle USB suspend
  241. if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SUSPEND)
  242. {
  243. // Clear USB suspend interrupt
  244. USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SUSPEND);
  245. #if HAL_UART_USB_SUSPEND
  246. // Take the chip into PM1 until a USB resume is deteceted.
  247. usbsuspEnter();
  248. #endif
  249. // Running again; first clear RESUME interrupt
  250. USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESUME);
  251. }
  252. }
  253. /***********************************************************************************
  254. * @fn halUartPollRx
  255. *
  256. * @brief Poll for data from USB.
  257. *
  258. * @param none
  259. *
  260. * @return none
  261. */
  262. static void halUartPollRx(void)
  263. {
  264. uint8 cnt;
  265. uint8 ep = USBFW_GET_SELECTED_ENDPOINT();
  266. USBFW_SELECT_ENDPOINT(4);
  267. // If the OUT endpoint has received a complete packet.
  268. if (USBFW_OUT_ENDPOINT_DISARMED())
  269. {
  270. halIntState_t intState;
  271. HAL_ENTER_CRITICAL_SECTION(intState);
  272. // Get length of USB packet, this operation must not be interrupted.
  273. cnt = USBFW_GET_OUT_ENDPOINT_COUNT_LOW();
  274. cnt += USBFW_GET_OUT_ENDPOINT_COUNT_HIGH() >> 8;
  275. HAL_EXIT_CRITICAL_SECTION(intState);
  276. while (cnt--)
  277. {
  278. halUartRxQ[halUartRxT++] = USBF4;
  279. }
  280. USBFW_ARM_OUT_ENDPOINT();
  281. #if !defined HAL_SB_BOOT_CODE
  282. // If the USB has transferred in more Rx bytes, reset the Rx idle timer.
  283. // Re-sync the shadow on any 1st byte(s) received.
  284. if (rxTick == 0)
  285. {
  286. rxShdw = ST0;
  287. }
  288. rxTick = HAL_UART_USB_IDLE;
  289. #endif
  290. }
  291. #if !defined HAL_SB_BOOT_CODE
  292. else if (rxTick)
  293. {
  294. // Use the LSB of the sleep timer (ST0 must be read first anyway).
  295. uint8 decr = ST0 - rxShdw;
  296. if (rxTick > decr)
  297. {
  298. rxTick -= decr;
  299. rxShdw = ST0;
  300. }
  301. else
  302. {
  303. rxTick = 0;
  304. }
  305. }
  306. {
  307. uint8 evt = 0;
  308. cnt = halUartRxT - halUartRxH;
  309. if (cnt >= HAL_UART_USB_HIGH)
  310. {
  311. evt = HAL_UART_RX_ABOUT_FULL;
  312. }
  313. else if (cnt && !rxTick)
  314. {
  315. evt = HAL_UART_RX_TIMEOUT;
  316. }
  317. if (evt && (NULL != uartCB))
  318. {
  319. uartCB(0, evt);
  320. }
  321. }
  322. #endif
  323. USBFW_SELECT_ENDPOINT(ep);
  324. }
  325. /***********************************************************************************
  326. * @fn halUartPollTx
  327. *
  328. * @brief Poll for data to USB.
  329. *
  330. * @param none
  331. *
  332. * @return none
  333. */
  334. static void halUartPollTx(void)
  335. {
  336. uint8 ep = USBFW_GET_SELECTED_ENDPOINT();
  337. USBFW_SELECT_ENDPOINT(4);
  338. // If the IN endpoint is ready to accept data.
  339. if (USBFW_IN_ENDPOINT_DISARMED())
  340. {
  341. if (halUartTxT == halUartTxH)
  342. {
  343. #if !defined HAL_SB_BOOT_CODE
  344. if (!txMT)
  345. {
  346. txMT = TRUE;
  347. uartCB(0, HAL_UART_TX_EMPTY);
  348. }
  349. #endif
  350. }
  351. else
  352. {
  353. uint8 max = HAL_UART_USB_TX_MAX;
  354. do
  355. {
  356. USBF4 = halUartTxQ[halUartTxH++];
  357. } while ((halUartTxH != halUartTxT) && (0 != --max));
  358. USBFW_ARM_IN_ENDPOINT();
  359. }
  360. }
  361. USBFW_SELECT_ENDPOINT(ep);
  362. }
  363. /******************************************************************************
  364. ******************************************************************************/