123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- /**************************************************************************************************
- Filename: _hal_uart_usb.c
- Revised: $Date: 2012-03-27 14:53:26 -0700 (Tue, 27 Mar 2012) $
- Revision: $Revision: 29910 $
- Description: This file contains the interface to the H/W UART driver by USB.
- Copyright 2009-2012 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 "hal_uart.h"
- #if defined MT_TASK
- #include "MT_UART.h"
- #endif
- #include "usb_board_cfg.h"
- #include "usb_cdc.h"
- #include "usb_cdc_hooks.h"
- #include "usb_firmware_library_config.h"
- #include "usb_firmware_library_headers.h"
- /*********************************************************************
- * MACROS
- */
- #if !defined HAL_UART_BAUD_RATE
- #define HAL_UART_BAUD_RATE 115200
- #endif
- // The timeout tick is at 32-kHz, so multiply msecs by 33.
- #define HAL_UART_MSECS_TO_TICKS 33
- #if defined MT_TASK
- #define HAL_UART_USB_HIGH MT_UART_DEFAULT_THRESHOLD
- #define HAL_UART_USB_IDLE (MT_UART_DEFAULT_IDLE_TIMEOUT * HAL_UART_MSECS_TO_TICKS)
- #define HAL_UART_USB_RX_MAX MT_UART_DEFAULT_MAX_RX_BUFF
- #else
- #if !defined HAL_UART_USB_HIGH
- #define HAL_UART_USB_HIGH (HAL_UART_USB_RX_MAX / 2 - 16)
- #endif
- #if !defined HAL_UART_USB_IDLE
- #define HAL_UART_USB_IDLE (6 * HAL_UART_MSECS_TO_TICKS)
- #endif
- #if !defined HAL_UART_USB_RX_MAX
- #define HAL_UART_USB_RX_MAX 128
- #endif
- #endif
- // Max USB packet size, per specification; see also usb_cdc_descriptor.s51
- #if !defined HAL_UART_USB_TX_MAX
- #define HAL_UART_USB_TX_MAX 64
- #endif
- /***********************************************************************************
- * EXTERNAL VARIABLES
- */
- /***********************************************************************************
- * GLOBAL VARIABLES
- */
- /***********************************************************************************
- * LOCAL DATA
- */
- static uint8 halUartRxH, halUartRxT, halUartRxQ[256];
- static uint8 halUartTxH, halUartTxT, halUartTxQ[256];
- #if !defined HAL_SB_BOOT_CODE
- static uint8 rxTick;
- static uint8 rxShdw;
- static uint8 txMT;
- static halUARTCBack_t uartCB;
- #endif
- /***********************************************************************************
- * LOCAL FUNCTIONS
- */
- static void HalUARTInitUSB(void);
- static void HalUARTPollUSB(void);
- static void halUartPollEvt(void);
- static void halUartPollRx(void);
- static void halUartPollTx(void);
- /******************************************************************************
- * FUNCTIONS
- */
- /***********************************************************************************
- * @fn usbUartInitUSB
- *
- * @brief USB UART init function.
- * - Set initial line decoding to 8/NONE/1.
- * - Initialise the USB Firmware Library and the USB controller.
- *
- * @param none
- *
- * @return none
- */
- void HalUARTInitUSB(void)
- {
- // Set default line coding.
- currentLineCoding.dteRate = HAL_UART_BAUD_RATE;
- currentLineCoding.charFormat = CDC_CHAR_FORMAT_1_STOP_BIT;
- currentLineCoding.parityType = CDC_PARITY_TYPE_NONE;
- currentLineCoding.dataBits = 8;
- // Init USB library
- usbfwInit();
- // Initialize the USB interrupt handler with bit mask containing all processed USBIRQ events
- usbirqInit(0xFFFF);
- #if defined HAL_SB_BOOT_CODE
- HAL_USB_PULLUP_ENABLE(); // Enable pullup on D+.
- #else
- txMT = TRUE;
- #endif
- }
- /******************************************************************************
- * @fn HalUARTUnInitUSB
- *
- * @brief UnInitialize the USB.
- *
- * @param none
- *
- * @return none
- *****************************************************************************/
- static void HalUARTUnInitUSB(void)
- {
- P2IEN = 0;
- IEN2 = 0;
- HAL_USB_PULLUP_DISABLE();
- HAL_USB_DISABLE;
- }
- #if !defined HAL_SB_BOOT_CODE
- /******************************************************************************
- * @fn HalUARTOpenUSB
- *
- * @brief Open a port according tp the configuration specified by parameter.
- *
- * @param config - contains configuration information
- *
- * @return none
- *****************************************************************************/
- static void HalUARTOpenUSB(halUARTCfg_t *config)
- {
- // Synchronize initial value to any value between 0 and 255
- halUartRxH = halUartRxT;
- uartCB = config->callBackFunc;
- (void)config;
- HAL_USB_PULLUP_ENABLE(); // Enable pullup on D+.
- }
- #endif
- /***********************************************************************************
- * @fn HalUartPollUSB
- *
- * @brief The USB UART main task function. Should be called from the OSAL main loop.
- *
- * @param none
- *
- * @return none
- */
- void HalUARTPollUSB(void)
- {
- #if defined HAL_SB_BOOT_CODE
- while (USBIF) usbirqHandler();
- #endif
- halUartPollEvt();
- halUartPollRx();
- halUartPollTx();
- }
- uint8 HalUARTRx(uint8 *buf, uint8 max);
- uint8 HalUARTRx(uint8 *buf, uint8 max)
- {
- uint8 cnt = 0;
- while ((halUartRxH != halUartRxT) && (cnt < max))
- {
- *buf++ = halUartRxQ[halUartRxH++];
- cnt++;
- }
- return cnt;
- }
- void HalUARTTx(uint8 *buf, uint8 cnt);
- void HalUARTTx(uint8 *buf, uint8 cnt)
- {
- while (cnt--)
- {
- halUartTxQ[halUartTxT++] = *buf++;
- }
- #if !defined HAL_SB_BOOT_CODE
- txMT = FALSE;
- #endif
- }
- /**************************************************************************************************
- * @fn HalUARTRxAvailUSB()
- *
- * @brief Calculate Rx Buffer length - the number of bytes in the buffer.
- *
- * @param none
- *
- * @return length of current Rx Buffer
- **************************************************************************************************/
- static uint16 HalUARTRxAvailUSB(void)
- {
- return ((halUartRxT >= halUartRxH)?
- halUartRxT - halUartRxH : sizeof(halUartRxQ) - halUartRxH + halUartRxT);
- }
- /***********************************************************************************
- * @fn halUartPollEvt
- *
- * @brief Poll for USB events which are not directly related to the UART.
- *
- * @param none
- *
- * @return none
- */
- static void halUartPollEvt(void)
- {
- // Handle reset signaling on the bus
- if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_RESET)
- {
- USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESET);
- usbfwResetHandler();
- }
- // Handle packets on EP0
- if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SETUP)
- {
- USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SETUP);
- usbfwSetupHandler();
- }
- // Handle USB suspend
- if (USBIRQ_GET_EVENT_MASK() & USBIRQ_EVENT_SUSPEND)
- {
- // Clear USB suspend interrupt
- USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_SUSPEND);
- #if HAL_UART_USB_SUSPEND
- // Take the chip into PM1 until a USB resume is deteceted.
- usbsuspEnter();
- #endif
- // Running again; first clear RESUME interrupt
- USBIRQ_CLEAR_EVENTS(USBIRQ_EVENT_RESUME);
- }
- }
- /***********************************************************************************
- * @fn halUartPollRx
- *
- * @brief Poll for data from USB.
- *
- * @param none
- *
- * @return none
- */
- static void halUartPollRx(void)
- {
- uint8 cnt;
- uint8 ep = USBFW_GET_SELECTED_ENDPOINT();
- USBFW_SELECT_ENDPOINT(4);
- // If the OUT endpoint has received a complete packet.
- if (USBFW_OUT_ENDPOINT_DISARMED())
- {
- halIntState_t intState;
- HAL_ENTER_CRITICAL_SECTION(intState);
- // Get length of USB packet, this operation must not be interrupted.
- cnt = USBFW_GET_OUT_ENDPOINT_COUNT_LOW();
- cnt += USBFW_GET_OUT_ENDPOINT_COUNT_HIGH() >> 8;
- HAL_EXIT_CRITICAL_SECTION(intState);
- while (cnt--)
- {
- halUartRxQ[halUartRxT++] = USBF4;
- }
- USBFW_ARM_OUT_ENDPOINT();
- #if !defined HAL_SB_BOOT_CODE
- // If the USB has transferred in more Rx bytes, reset the Rx idle timer.
- // Re-sync the shadow on any 1st byte(s) received.
- if (rxTick == 0)
- {
- rxShdw = ST0;
- }
- rxTick = HAL_UART_USB_IDLE;
- #endif
- }
- #if !defined HAL_SB_BOOT_CODE
- else if (rxTick)
- {
- // Use the LSB of the sleep timer (ST0 must be read first anyway).
- uint8 decr = ST0 - rxShdw;
- if (rxTick > decr)
- {
- rxTick -= decr;
- rxShdw = ST0;
- }
- else
- {
- rxTick = 0;
- }
- }
- {
- uint8 evt = 0;
- cnt = halUartRxT - halUartRxH;
- if (cnt >= HAL_UART_USB_HIGH)
- {
- evt = HAL_UART_RX_ABOUT_FULL;
- }
- else if (cnt && !rxTick)
- {
- evt = HAL_UART_RX_TIMEOUT;
- }
- if (evt && (NULL != uartCB))
- {
- uartCB(0, evt);
- }
- }
- #endif
- USBFW_SELECT_ENDPOINT(ep);
- }
- /***********************************************************************************
- * @fn halUartPollTx
- *
- * @brief Poll for data to USB.
- *
- * @param none
- *
- * @return none
- */
- static void halUartPollTx(void)
- {
- uint8 ep = USBFW_GET_SELECTED_ENDPOINT();
- USBFW_SELECT_ENDPOINT(4);
- // If the IN endpoint is ready to accept data.
- if (USBFW_IN_ENDPOINT_DISARMED())
- {
- if (halUartTxT == halUartTxH)
- {
- #if !defined HAL_SB_BOOT_CODE
- if (!txMT)
- {
- txMT = TRUE;
- uartCB(0, HAL_UART_TX_EMPTY);
- }
- #endif
- }
- else
- {
- uint8 max = HAL_UART_USB_TX_MAX;
- do
- {
- USBF4 = halUartTxQ[halUartTxH++];
- } while ((halUartTxH != halUartTxT) && (0 != --max));
- USBFW_ARM_IN_ENDPOINT();
- }
- }
- USBFW_SELECT_ENDPOINT(ep);
- }
- /******************************************************************************
- ******************************************************************************/
|