123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578 |
- /**************************************************************************************************
- Filename: _hal_uart_isr.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 ISR.
- Copyright 2006-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_types.h"
- #include "hal_assert.h"
- #include "hal_board.h"
- #include "hal_defs.h"
- #include "hal_mcu.h"
- #include "hal_uart.h"
- #if defined MT_TASK
- #include "MT_UART.h"
- #endif
- /*********************************************************************
- * MACROS
- */
- //#define HAL_UART_ASSERT(expr) HAL_ASSERT((expr))
- #define HAL_UART_ASSERT(expr)
- #define HAL_UART_ISR_RX_AVAIL() \
- (isrCfg.rxTail >= isrCfg.rxHead) ? \
- (isrCfg.rxTail - isrCfg.rxHead) : \
- (HAL_UART_ISR_RX_MAX - isrCfg.rxHead + isrCfg.rxTail)
- #define HAL_UART_ISR_TX_AVAIL() \
- (isrCfg.txHead > isrCfg.txTail) ? \
- (isrCfg.txHead - isrCfg.txTail - 1) : \
- (HAL_UART_ISR_TX_MAX - isrCfg.txTail + isrCfg.txHead - 1)
- /*********************************************************************
- * CONSTANTS
- */
- // UxCSR - USART Control and Status Register.
- #define CSR_MODE 0x80
- #define CSR_RE 0x40
- #define CSR_SLAVE 0x20
- #define CSR_FE 0x10
- #define CSR_ERR 0x08
- #define CSR_RX_BYTE 0x04
- #define CSR_TX_BYTE 0x02
- #define CSR_ACTIVE 0x01
- // UxUCR - USART UART Control Register.
- #define UCR_FLUSH 0x80
- #define UCR_FLOW 0x40
- #define UCR_D9 0x20
- #define UCR_BIT9 0x10
- #define UCR_PARITY 0x08
- #define UCR_SPB 0x04
- #define UCR_STOP 0x02
- #define UCR_START 0x01
- #define UTX0IE 0x04
- #define UTX1IE 0x08
- #define P2DIR_PRIPO 0xC0
- // Incompatible redefinitions result with more than one UART driver sub-module.
- #undef PxOUT
- #undef PxDIR
- #undef PxSEL
- #undef UxCSR
- #undef UxUCR
- #undef UxDBUF
- #undef UxBAUD
- #undef UxGCR
- #undef URXxIE
- #undef URXxIF
- #undef UTXxIE
- #undef UTXxIF
- #undef HAL_UART_PERCFG_BIT
- #undef HAL_UART_Px_RTS
- #undef HAL_UART_Px_CTS
- #undef HAL_UART_Px_RX_TX
- #if (HAL_UART_ISR == 1)
- #define PxOUT P0
- #define PxDIR P0DIR
- #define PxSEL P0SEL
- #define UxCSR U0CSR
- #define UxUCR U0UCR
- #define UxDBUF U0DBUF
- #define UxBAUD U0BAUD
- #define UxGCR U0GCR
- #define URXxIE URX0IE
- #define URXxIF URX0IF
- #define UTXxIE UTX0IE
- #define UTXxIF UTX0IF
- #else
- #define PxOUT P1
- #define PxDIR P1DIR
- #define PxSEL P1SEL
- #define UxCSR U1CSR
- #define UxUCR U1UCR
- #define UxDBUF U1DBUF
- #define UxBAUD U1BAUD
- #define UxGCR U1GCR
- #define URXxIE URX1IE
- #define URXxIF URX1IF
- #define UTXxIE UTX1IE
- #define UTXxIF UTX1IF
- #endif
- #if (HAL_UART_ISR == 1)
- #define HAL_UART_PERCFG_BIT 0x01 // USART0 on P0, Alt-1; so clear this bit.
- #define HAL_UART_Px_RX_TX 0x0C // Peripheral I/O Select for Rx/Tx.
- #define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.
- #define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.
- #else
- #define HAL_UART_PERCFG_BIT 0x02 // USART1 on P1, Alt-2; so set this bit.
- #define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.
- #define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.
- #define HAL_UART_Px_RX_TX 0xC0 // Peripheral I/O Select for Rx/Tx.
- #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_ISR_TX_MAX MT_UART_DEFAULT_MAX_TX_BUFF
- #define HAL_UART_ISR_RX_MAX MT_UART_DEFAULT_MAX_RX_BUFF
- #define HAL_UART_ISR_HIGH MT_UART_DEFAULT_THRESHOLD
- #define HAL_UART_ISR_IDLE (MT_UART_DEFAULT_IDLE_TIMEOUT * HAL_UART_MSECS_TO_TICKS)
- #else
- #if !defined HAL_UART_ISR_RX_MAX
- #define HAL_UART_ISR_RX_MAX 128
- #endif
- #if !defined HAL_UART_ISR_TX_MAX
- #define HAL_UART_ISR_TX_MAX HAL_UART_ISR_RX_MAX
- #endif
- #if !defined HAL_UART_ISR_HIGH
- #define HAL_UART_ISR_HIGH (HAL_UART_ISR_RX_MAX / 2 - 16)
- #endif
- #if !defined HAL_UART_ISR_IDLE
- #define HAL_UART_ISR_IDLE (6 * HAL_UART_MSECS_TO_TICKS)
- #endif
- #endif
- /*********************************************************************
- * TYPEDEFS
- */
- typedef struct
- {
- uint8 rxBuf[HAL_UART_ISR_RX_MAX];
- #if HAL_UART_ISR_RX_MAX < 256
- uint8 rxHead;
- volatile uint8 rxTail;
- #else
- uint16 rxHead;
- volatile uint16 rxTail;
- #endif
- uint8 rxTick;
- uint8 rxShdw;
- uint8 txBuf[HAL_UART_ISR_TX_MAX];
- #if HAL_UART_ISR_TX_MAX < 256
- volatile uint8 txHead;
- uint8 txTail;
- #else
- volatile uint16 txHead;
- uint16 txTail;
- #endif
- uint8 txMT;
- halUARTCBack_t uartCB;
- } uartISRCfg_t;
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- /*********************************************************************
- * GLOBAL FUNCTIONS
- */
- /*********************************************************************
- * LOCAL VARIABLES
- */
- static uartISRCfg_t isrCfg;
- /*********************************************************************
- * LOCAL FUNCTIONS
- */
- static void HalUARTInitISR(void);
- static void HalUARTOpenISR(halUARTCfg_t *config);
- uint16 HalUARTReadISR(uint8 *buf, uint16 len);
- uint16 HalUARTWriteISR(uint8 *buf, uint16 len);
- static void HalUARTPollISR(void);
- static uint16 HalUARTRxAvailISR(void);
- static void HalUARTSuspendISR(void);
- static void HalUARTResumeISR(void);
- /******************************************************************************
- * @fn HalUARTInitISR
- *
- * @brief Initialize the UART
- *
- * @param none
- *
- * @return none
- *****************************************************************************/
- static void HalUARTInitISR(void)
- {
- // Set P2 priority - USART0 over USART1 if both are defined.
- P2DIR &= ~P2DIR_PRIPO;
- P2DIR |= HAL_UART_PRIPO;
- #if (HAL_UART_ISR == 1)
- PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O location to P0.
- #else
- PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O location to P1.
- #endif
- PxSEL |= HAL_UART_Px_RX_TX; // Enable Tx and Rx on P1.
- ADCCFG &= ~HAL_UART_Px_RX_TX; // Make sure ADC doesnt use this.
- UxCSR = CSR_MODE; // Mode is UART Mode.
- UxUCR = UCR_FLUSH; // Flush it.
- }
- /******************************************************************************
- * @fn HalUARTUnInitISR
- *
- * @brief UnInitialize the UART.
- *
- * @param none
- *
- * @return none
- *****************************************************************************/
- static void HalUARTUnInitISR(void)
- {
- UxCSR = 0;
- URXxIE = 0;
- URXxIF = 0;
- IEN2 &= ~UTXxIE;
- UTXxIF = 0;
- }
- /******************************************************************************
- * @fn HalUARTOpenISR
- *
- * @brief Open a port according tp the configuration specified by parameter.
- *
- * @param config - contains configuration information
- *
- * @return none
- *****************************************************************************/
- static void HalUARTOpenISR(halUARTCfg_t *config)
- {
- isrCfg.uartCB = config->callBackFunc;
- // Only supporting subset of baudrate for code size - other is possible.
- HAL_UART_ASSERT((config->baudRate == HAL_UART_BR_9600) ||
- (config->baudRate == HAL_UART_BR_19200) ||
- (config->baudRate == HAL_UART_BR_38400) ||
- (config->baudRate == HAL_UART_BR_57600) ||
- (config->baudRate == HAL_UART_BR_115200));
-
- if (config->baudRate == HAL_UART_BR_57600 ||
- config->baudRate == HAL_UART_BR_115200)
- {
- UxBAUD = 216;
- }
- else
- {
- UxBAUD = 59;
- }
-
- switch (config->baudRate)
- {
- case HAL_UART_BR_9600:
- UxGCR = 8;
- break;
- case HAL_UART_BR_19200:
- UxGCR = 9;
- break;
- case HAL_UART_BR_38400:
- case HAL_UART_BR_57600:
- UxGCR = 10;
- break;
- default:
- UxGCR = 11;
- break;
- }
- // 8 bits/char; no parity; 1 stop bit; stop bit hi.
- if (config->flowControl)
- {
- UxUCR = UCR_FLOW | UCR_STOP;
- PxSEL |= HAL_UART_Px_RTS | HAL_UART_Px_CTS;
- }
- else
- {
- UxUCR = UCR_STOP;
- }
- UxCSR |= CSR_RE;
- URXxIE = 1;
- UTXxIF = 1; // Prime the ISR pump.
- }
- /*****************************************************************************
- * @fn HalUARTReadISR
- *
- * @brief Read a buffer from the UART
- *
- * @param buf - valid data buffer at least 'len' bytes in size
- * len - max length number of bytes to copy to 'buf'
- *
- * @return length of buffer that was read
- *****************************************************************************/
- uint16 HalUARTReadISR(uint8 *buf, uint16 len)
- {
- uint16 cnt = 0;
- while ((isrCfg.rxHead != isrCfg.rxTail) && (cnt < len))
- {
- *buf++ = isrCfg.rxBuf[isrCfg.rxHead++];
- if (isrCfg.rxHead >= HAL_UART_ISR_RX_MAX)
- {
- isrCfg.rxHead = 0;
- }
- cnt++;
- }
- return cnt;
- }
- /******************************************************************************
- * @fn HalUARTWriteISR
- *
- * @brief Write a buffer to the UART.
- *
- * @param buf - pointer to the buffer that will be written, not freed
- * len - length of
- *
- * @return length of the buffer that was sent
- *****************************************************************************/
- uint16 HalUARTWriteISR(uint8 *buf, uint16 len)
- {
- uint16 cnt;
- // Enforce all or none.
- if (HAL_UART_ISR_TX_AVAIL() < len)
- {
- return 0;
- }
- for (cnt = 0; cnt < len; cnt++)
- {
- isrCfg.txBuf[isrCfg.txTail] = *buf++;
- isrCfg.txMT = 0;
- if (isrCfg.txTail >= HAL_UART_ISR_TX_MAX-1)
- {
- isrCfg.txTail = 0;
- }
- else
- {
- isrCfg.txTail++;
- }
- // Keep re-enabling ISR as it might be keeping up with this loop due to other ints.
- IEN2 |= UTXxIE;
- }
- return cnt;
- }
- /******************************************************************************
- * @fn HalUARTPollISR
- *
- * @brief Poll a USART module implemented by ISR.
- *
- * @param none
- *
- * @return none
- *****************************************************************************/
- static void HalUARTPollISR(void)
- {
- if (isrCfg.uartCB != NULL)
- {
- uint16 cnt = HAL_UART_ISR_RX_AVAIL();
- uint8 evt = 0;
- if (isrCfg.rxTick)
- {
- // Use the LSB of the sleep timer (ST0 must be read first anyway).
- uint8 decr = ST0 - isrCfg.rxShdw;
- if (isrCfg.rxTick > decr)
- {
- isrCfg.rxTick -= decr;
- }
- else
- {
- isrCfg.rxTick = 0;
- }
- }
- isrCfg.rxShdw = ST0;
- if (cnt >= HAL_UART_ISR_RX_MAX-1)
- {
- evt = HAL_UART_RX_FULL;
- }
- else if (cnt >= HAL_UART_ISR_HIGH)
- {
- evt = HAL_UART_RX_ABOUT_FULL;
- }
- else if (cnt && !isrCfg.rxTick)
- {
- evt = HAL_UART_RX_TIMEOUT;
- }
- if (isrCfg.txMT)
- {
- isrCfg.txMT = 0;
- evt |= HAL_UART_TX_EMPTY;
- }
- if (evt)
- {
- isrCfg.uartCB(HAL_UART_ISR-1, evt);
- }
- }
- }
- /**************************************************************************************************
- * @fn HalUARTRxAvailISR()
- *
- * @brief Calculate Rx Buffer length - the number of bytes in the buffer.
- *
- * @param none
- *
- * @return length of current Rx Buffer
- **************************************************************************************************/
- static uint16 HalUARTRxAvailISR(void)
- {
- return HAL_UART_ISR_RX_AVAIL();
- }
- /******************************************************************************
- * @fn HalUARTSuspendISR
- *
- * @brief Suspend UART hardware before entering PM mode 1, 2 or 3.
- *
- * @param None
- *
- * @return None
- *****************************************************************************/
- static void HalUARTSuspendISR( void )
- {
- UxCSR &= ~CSR_RE;
- }
- /******************************************************************************
- * @fn HalUARTResumeISR
- *
- * @brief Resume UART hardware after exiting PM mode 1, 2 or 3.
- *
- * @param None
- *
- * @return None
- *****************************************************************************/
- static void HalUARTResumeISR( void )
- {
- UxUCR |= UCR_FLUSH;
- UxCSR |= CSR_RE;
- }
- /***************************************************************************************************
- * @fn halUartRxIsr
- *
- * @brief UART Receive Interrupt
- *
- * @param None
- *
- * @return None
- ***************************************************************************************************/
- #if (HAL_UART_ISR == 1)
- HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )
- #else
- HAL_ISR_FUNCTION( halUart1RxIsr, URX1_VECTOR )
- #endif
- {
- uint8 tmp = UxDBUF;
- isrCfg.rxBuf[isrCfg.rxTail] = tmp;
- // Re-sync the shadow on any 1st byte received.
- if (isrCfg.rxHead == isrCfg.rxTail)
- {
- isrCfg.rxShdw = ST0;
- }
- if (++isrCfg.rxTail >= HAL_UART_ISR_RX_MAX)
- {
- isrCfg.rxTail = 0;
- }
- isrCfg.rxTick = HAL_UART_ISR_IDLE;
- }
- /***************************************************************************************************
- * @fn halUartTxIsr
- *
- * @brief UART Transmit Interrupt
- *
- * @param None
- *
- * @return None
- ***************************************************************************************************/
- #if (HAL_UART_ISR == 1)
- HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR )
- #else
- HAL_ISR_FUNCTION( halUart1TxIsr, UTX1_VECTOR )
- #endif
- {
- if (isrCfg.txHead == isrCfg.txTail)
- {
- IEN2 &= ~UTXxIE;
- isrCfg.txMT = 1;
- }
- else
- {
- UTXxIF = 0;
- UxDBUF = isrCfg.txBuf[isrCfg.txHead++];
- if (isrCfg.txHead >= HAL_UART_ISR_TX_MAX)
- {
- isrCfg.txHead = 0;
- }
- }
- }
- /******************************************************************************
- ******************************************************************************/
|