xref: /btstack/port/archive/msp-exp430f5438-cc2564b/src/hal_uart_dma.c (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
11664436fSMatthias Ringwald /*
21664436fSMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
31664436fSMatthias Ringwald  *
41664436fSMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
51664436fSMatthias Ringwald  * modification, are permitted provided that the following conditions
61664436fSMatthias Ringwald  * are met:
71664436fSMatthias Ringwald  *
81664436fSMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
91664436fSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
101664436fSMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
111664436fSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
121664436fSMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
131664436fSMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
141664436fSMatthias Ringwald  *    contributors may be used to endorse or promote products derived
151664436fSMatthias Ringwald  *    from this software without specific prior written permission.
161664436fSMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
171664436fSMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
181664436fSMatthias Ringwald  *    monetary gain.
191664436fSMatthias Ringwald  *
201664436fSMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
211664436fSMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
221664436fSMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*2fca4dadSMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*2fca4dadSMilanka Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
251664436fSMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
261664436fSMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
271664436fSMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
281664436fSMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
291664436fSMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
301664436fSMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311664436fSMatthias Ringwald  * SUCH DAMAGE.
321664436fSMatthias Ringwald  *
331664436fSMatthias Ringwald  * Please inquire about commercial licensing options at
341664436fSMatthias Ringwald  * [email protected]
351664436fSMatthias Ringwald  *
361664436fSMatthias Ringwald  */
371664436fSMatthias Ringwald 
381664436fSMatthias Ringwald /**
391664436fSMatthias Ringwald  * @file  hal_bt.c
401664436fSMatthias Ringwald  ***************************************************************************/
411664436fSMatthias Ringwald #include <stdint.h>
421664436fSMatthias Ringwald 
431664436fSMatthias Ringwald #include <msp430x54x.h>
441664436fSMatthias Ringwald #include "hal_compat.h"
451664436fSMatthias Ringwald 
461664436fSMatthias Ringwald #include "hal_uart_dma.h"
471664436fSMatthias Ringwald 
481664436fSMatthias Ringwald extern void hal_cpu_set_uart_needed_during_sleep(uint8_t enabled);
491664436fSMatthias Ringwald 
501664436fSMatthias Ringwald // debugging only
511664436fSMatthias Ringwald // #include <stdio.h>
521664436fSMatthias Ringwald 
531664436fSMatthias Ringwald #define BT_PORT_OUT      P9OUT
541664436fSMatthias Ringwald #define BT_PORT_SEL      P9SEL
551664436fSMatthias Ringwald #define BT_PORT_DIR      P9DIR
561664436fSMatthias Ringwald #define BT_PORT_REN      P9REN
571664436fSMatthias Ringwald #define BT_PIN_TXD       BIT4
581664436fSMatthias Ringwald #define BT_PIN_RXD       BIT5
591664436fSMatthias Ringwald 
601664436fSMatthias Ringwald // RXD P9.5
611664436fSMatthias Ringwald // TXD P9.4
621664436fSMatthias Ringwald // RTS P1.4
631664436fSMatthias Ringwald // CTS P1.3
641664436fSMatthias Ringwald 
dummy_handler(void)651664436fSMatthias Ringwald void dummy_handler(void){};
661664436fSMatthias Ringwald 
671664436fSMatthias Ringwald // rx state
681664436fSMatthias Ringwald static uint16_t  bytes_to_read = 0;
691664436fSMatthias Ringwald static uint8_t * rx_buffer_ptr = 0;
701664436fSMatthias Ringwald 
711664436fSMatthias Ringwald // tx state
721664436fSMatthias Ringwald static uint16_t  bytes_to_write = 0;
731664436fSMatthias Ringwald static uint8_t * tx_buffer_ptr = 0;
741664436fSMatthias Ringwald 
751664436fSMatthias Ringwald // handlers
761664436fSMatthias Ringwald static void (*rx_done_handler)(void) = dummy_handler;
771664436fSMatthias Ringwald static void (*tx_done_handler)(void) = dummy_handler;
781664436fSMatthias Ringwald static void (*cts_irq_handler)(void) = dummy_handler;
791664436fSMatthias Ringwald 
801664436fSMatthias Ringwald /**
811664436fSMatthias Ringwald  * @brief  Initializes the serial communications peripheral and GPIO ports
821664436fSMatthias Ringwald  *         to communicate with the PAN BT .. assuming 16 Mhz CPU
831664436fSMatthias Ringwald  *
841664436fSMatthias Ringwald  * @param  none
851664436fSMatthias Ringwald  *
861664436fSMatthias Ringwald  * @return none
871664436fSMatthias Ringwald  */
hal_uart_dma_init(void)881664436fSMatthias Ringwald void hal_uart_dma_init(void)
891664436fSMatthias Ringwald {
901664436fSMatthias Ringwald     BT_PORT_SEL |= BT_PIN_RXD + BT_PIN_TXD;
911664436fSMatthias Ringwald     BT_PORT_DIR |= BT_PIN_TXD;
921664436fSMatthias Ringwald     BT_PORT_DIR &= ~BT_PIN_RXD;
931664436fSMatthias Ringwald 
941664436fSMatthias Ringwald     // set BT RTS (P1.4)
951664436fSMatthias Ringwald     P1SEL &= ~BIT4;  // = 0 - I/O
961664436fSMatthias Ringwald     P1DIR |=  BIT4;  // = 1 - Output
971664436fSMatthias Ringwald     P1OUT |=  BIT4;  // = 1 - RTS high -> stop
981664436fSMatthias Ringwald 
991664436fSMatthias Ringwald     // set BT CTS
1001664436fSMatthias Ringwald     P1SEL &= ~BIT3;  // = 0 - I/O
1011664436fSMatthias Ringwald     P1DIR &= ~BIT3;  // = 0 - Input    P1DIR |=  BIT4; // RTS
1021664436fSMatthias Ringwald 
1031664436fSMatthias Ringwald     // set BT SHUTDOWN (P8.2) to 1 (active low)
1041664436fSMatthias Ringwald     P8SEL &= ~BIT2;  // = 0 - I/O
1051664436fSMatthias Ringwald     P8DIR |=  BIT2;  // = 1 - Output
1061664436fSMatthias Ringwald     P8OUT |=  BIT2;  // = 1 - Active low -> ok
1071664436fSMatthias Ringwald 
1081664436fSMatthias Ringwald     // Enable ACLK to provide 32 kHz clock to Bluetooth module
1091664436fSMatthias Ringwald     P11SEL |= BIT0;
1101664436fSMatthias Ringwald     P11DIR |= BIT0;
1111664436fSMatthias Ringwald 
1121664436fSMatthias Ringwald     // wait for Bluetooth to power up properly after providing 32khz clock
1131664436fSMatthias Ringwald     waitAboutOneSecond();
1141664436fSMatthias Ringwald 
1151664436fSMatthias Ringwald     UCA2CTL1 |= UCSWRST;              //Reset State
1161664436fSMatthias Ringwald     UCA2CTL0 = UCMODE_0;
1171664436fSMatthias Ringwald 
1181664436fSMatthias Ringwald     UCA2CTL0 &= ~UC7BIT;              // 8bit char
1191664436fSMatthias Ringwald     UCA2CTL1 |= UCSSEL_2;
1201664436fSMatthias Ringwald 
1211664436fSMatthias Ringwald     UCA2CTL1 &= ~UCSWRST;             // continue
1221664436fSMatthias Ringwald 
1231664436fSMatthias Ringwald     hal_uart_dma_set_baud(115200);
1241664436fSMatthias Ringwald }
1251664436fSMatthias Ringwald 
1261664436fSMatthias Ringwald /**
1271664436fSMatthias Ringwald 
1281664436fSMatthias Ringwald  UART used in low-frequency mode
1291664436fSMatthias Ringwald  In this mode, the maximum USCI baud rate is one-third the UART source clock frequency BRCLK.
1301664436fSMatthias Ringwald 
1311664436fSMatthias Ringwald  16000000 /  576000 = 277.77
1321664436fSMatthias Ringwald  16000000 /  115200 = 138.88
1331664436fSMatthias Ringwald  16000000 /  921600 =  17.36
1341664436fSMatthias Ringwald  16000000 / 1000000 =  16.00
1351664436fSMatthias Ringwald  16000000 / 2000000 =   8.00
1361664436fSMatthias Ringwald  16000000 / 2400000 =   6.66
1371664436fSMatthias Ringwald  16000000 / 3000000 =   3.33
1381664436fSMatthias Ringwald  16000000 / 4000000 =   2.00
1391664436fSMatthias Ringwald 
1401664436fSMatthias Ringwald  */
hal_uart_dma_set_baud(uint32_t baud)1411664436fSMatthias Ringwald int hal_uart_dma_set_baud(uint32_t baud){
1421664436fSMatthias Ringwald 
1431664436fSMatthias Ringwald     int result = 0;
1441664436fSMatthias Ringwald 
1451664436fSMatthias Ringwald     UCA2CTL1 |= UCSWRST;              //Reset State
1461664436fSMatthias Ringwald 
1471664436fSMatthias Ringwald     switch (baud){
1481664436fSMatthias Ringwald 
1491664436fSMatthias Ringwald         case 4000000:
1501664436fSMatthias Ringwald             UCA2BR0 = 2;
1511664436fSMatthias Ringwald             UCA2BR1 = 0;
1521664436fSMatthias Ringwald             UCA2MCTL= 0 << 1;  // + 0.000
1531664436fSMatthias Ringwald             break;
1541664436fSMatthias Ringwald 
1551664436fSMatthias Ringwald         case 3000000:
1561664436fSMatthias Ringwald             UCA2BR0 = 3;
1571664436fSMatthias Ringwald             UCA2BR1 = 0;
1581664436fSMatthias Ringwald             UCA2MCTL= 3 << 1;  // + 0.375
1591664436fSMatthias Ringwald             break;
1601664436fSMatthias Ringwald 
1611664436fSMatthias Ringwald         case 2400000:
1621664436fSMatthias Ringwald             UCA2BR0 = 6;
1631664436fSMatthias Ringwald             UCA2BR1 = 0;
1641664436fSMatthias Ringwald             UCA2MCTL= 5 << 1;  // + 0.625
1651664436fSMatthias Ringwald             break;
1661664436fSMatthias Ringwald 
1671664436fSMatthias Ringwald         case 2000000:
1681664436fSMatthias Ringwald             UCA2BR0 = 8;
1691664436fSMatthias Ringwald             UCA2BR1 = 0;
1701664436fSMatthias Ringwald             UCA2MCTL= 0 << 1;  // + 0.000
1711664436fSMatthias Ringwald             break;
1721664436fSMatthias Ringwald 
1731664436fSMatthias Ringwald         case 1000000:
1741664436fSMatthias Ringwald             UCA2BR0 = 16;
1751664436fSMatthias Ringwald             UCA2BR1 = 0;
1761664436fSMatthias Ringwald             UCA2MCTL= 0 << 1;  // + 0.000
1771664436fSMatthias Ringwald             break;
1781664436fSMatthias Ringwald 
1791664436fSMatthias Ringwald         case 921600:
1801664436fSMatthias Ringwald             UCA2BR0 = 17;
1811664436fSMatthias Ringwald             UCA2BR1 = 0;
1821664436fSMatthias Ringwald             UCA2MCTL= 7 << 1;  // 3 << 1;  // + 0.375
1831664436fSMatthias Ringwald             break;
1841664436fSMatthias Ringwald 
1851664436fSMatthias Ringwald         case 115200:
1861664436fSMatthias Ringwald             UCA2BR0 = 138;  // from family user guide
1871664436fSMatthias Ringwald             UCA2BR1 = 0;
1881664436fSMatthias Ringwald             UCA2MCTL= 7 << 1;  // + 0.875
1891664436fSMatthias Ringwald             break;
1901664436fSMatthias Ringwald 
1911664436fSMatthias Ringwald         case 57600:
1921664436fSMatthias Ringwald             UCA2BR0 = 21;
1931664436fSMatthias Ringwald             UCA2BR1 = 1;
1941664436fSMatthias Ringwald             UCA2MCTL= 7 << 1;  // + 0.875
1951664436fSMatthias Ringwald             break;
1961664436fSMatthias Ringwald 
1971664436fSMatthias Ringwald         default:
1981664436fSMatthias Ringwald             result = -1;
1991664436fSMatthias Ringwald             break;
2001664436fSMatthias Ringwald     }
2011664436fSMatthias Ringwald 
2021664436fSMatthias Ringwald     UCA2CTL1 &= ~UCSWRST;             // continue
2031664436fSMatthias Ringwald 
2041664436fSMatthias Ringwald     return result;
2051664436fSMatthias Ringwald }
2061664436fSMatthias Ringwald 
hal_uart_dma_set_block_received(void (* the_block_handler)(void))2071664436fSMatthias Ringwald void hal_uart_dma_set_block_received( void (*the_block_handler)(void)){
2081664436fSMatthias Ringwald     rx_done_handler = the_block_handler;
2091664436fSMatthias Ringwald }
2101664436fSMatthias Ringwald 
hal_uart_dma_set_block_sent(void (* the_block_handler)(void))2111664436fSMatthias Ringwald void hal_uart_dma_set_block_sent( void (*the_block_handler)(void)){
2121664436fSMatthias Ringwald     tx_done_handler = the_block_handler;
2131664436fSMatthias Ringwald }
2141664436fSMatthias Ringwald 
hal_uart_dma_set_csr_irq_handler(void (* the_irq_handler)(void))2151664436fSMatthias Ringwald void hal_uart_dma_set_csr_irq_handler( void (*the_irq_handler)(void)){
2161664436fSMatthias Ringwald     if (the_irq_handler){
2171664436fSMatthias Ringwald         P1IFG  =  0;     // no IRQ pending
2181664436fSMatthias Ringwald         P1IV   =  0;     // no IRQ pending
2191664436fSMatthias Ringwald         P1IES &= ~BIT3;  // IRQ on 0->1 transition
2201664436fSMatthias Ringwald         P1IE  |=  BIT3;  // enable IRQ for P1.3
2211664436fSMatthias Ringwald         cts_irq_handler = the_irq_handler;
2221664436fSMatthias Ringwald         return;
2231664436fSMatthias Ringwald     }
2241664436fSMatthias Ringwald 
2251664436fSMatthias Ringwald     P1IE  &= ~BIT3;
2261664436fSMatthias Ringwald     cts_irq_handler = dummy_handler;
2271664436fSMatthias Ringwald }
2281664436fSMatthias Ringwald 
2291664436fSMatthias Ringwald /**********************************************************************/
2301664436fSMatthias Ringwald /**
2311664436fSMatthias Ringwald  * @brief  Disables the serial communications peripheral and clears the GPIO
2321664436fSMatthias Ringwald  *         settings used to communicate with the BT.
2331664436fSMatthias Ringwald  *
2341664436fSMatthias Ringwald  * @param  none
2351664436fSMatthias Ringwald  *
2361664436fSMatthias Ringwald  * @return none
2371664436fSMatthias Ringwald  **************************************************************************/
hal_uart_dma_shutdown(void)2381664436fSMatthias Ringwald void hal_uart_dma_shutdown(void) {
2391664436fSMatthias Ringwald 
2401664436fSMatthias Ringwald     UCA2IE &= ~(UCRXIE | UCTXIE);
2411664436fSMatthias Ringwald     UCA2CTL1 = UCSWRST;                          //Reset State
2421664436fSMatthias Ringwald     BT_PORT_SEL &= ~( BT_PIN_RXD + BT_PIN_TXD );
2431664436fSMatthias Ringwald     BT_PORT_DIR |= BT_PIN_TXD;
2441664436fSMatthias Ringwald     BT_PORT_DIR |= BT_PIN_RXD;
2451664436fSMatthias Ringwald     BT_PORT_OUT &= ~(BT_PIN_TXD + BT_PIN_RXD);
2461664436fSMatthias Ringwald }
2471664436fSMatthias Ringwald 
hal_uart_dma_send_block(const uint8_t * data,uint16_t len)2481664436fSMatthias Ringwald void hal_uart_dma_send_block(const uint8_t * data, uint16_t len){
2491664436fSMatthias Ringwald 
2501664436fSMatthias Ringwald     // printf("hal_uart_dma_send_block, size %u\n\r", len);
2511664436fSMatthias Ringwald 
2521664436fSMatthias Ringwald     UCA2IE &= ~UCTXIE ;  // disable TX interrupts
2531664436fSMatthias Ringwald 
2541664436fSMatthias Ringwald     tx_buffer_ptr = (uint8_t *) data;
2551664436fSMatthias Ringwald     bytes_to_write = len;
2561664436fSMatthias Ringwald 
2571664436fSMatthias Ringwald     UCA2IE |= UCTXIE;    // enable TX interrupts
2581664436fSMatthias Ringwald }
2591664436fSMatthias Ringwald 
hal_uart_dma_enable_rx(void)2601664436fSMatthias Ringwald static inline void hal_uart_dma_enable_rx(void){
2611664436fSMatthias Ringwald     P1OUT &= ~BIT4;  // = 0 - RTS low -> ok
2621664436fSMatthias Ringwald }
2631664436fSMatthias Ringwald 
hal_uart_dma_disable_rx(void)2641664436fSMatthias Ringwald static inline void hal_uart_dma_disable_rx(void){
2651664436fSMatthias Ringwald     P1OUT |= BIT4;  // = 1 - RTS high -> stop
2661664436fSMatthias Ringwald }
2671664436fSMatthias Ringwald 
hal_uart_dma_receive_block(uint8_t * buffer,uint16_t len)2681664436fSMatthias Ringwald void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len){
2691664436fSMatthias Ringwald     // disable RX interrupts
2701664436fSMatthias Ringwald     UCA2IE &= ~UCRXIE ;
2711664436fSMatthias Ringwald 
2721664436fSMatthias Ringwald     rx_buffer_ptr = buffer;
2731664436fSMatthias Ringwald     bytes_to_read = len;
2741664436fSMatthias Ringwald 
2751664436fSMatthias Ringwald     // check if byte already received
2761664436fSMatthias Ringwald     int pending = UCA2IFG & UCRXIFG;
2771664436fSMatthias Ringwald 
2781664436fSMatthias Ringwald     // enable RX interrupts - will trigger ISR below if byte pending
2791664436fSMatthias Ringwald     UCA2IE |= UCRXIE;
2801664436fSMatthias Ringwald 
2811664436fSMatthias Ringwald     // if byte was pending, ISR controls RTS
2821664436fSMatthias Ringwald     if (!pending) {
2831664436fSMatthias Ringwald         hal_uart_dma_enable_rx();
2841664436fSMatthias Ringwald     }
2851664436fSMatthias Ringwald }
2861664436fSMatthias Ringwald 
hal_uart_dma_set_sleep(uint8_t sleep)2871664436fSMatthias Ringwald void hal_uart_dma_set_sleep(uint8_t sleep){
2881664436fSMatthias Ringwald     hal_cpu_set_uart_needed_during_sleep(!sleep);
2891664436fSMatthias Ringwald }
2901664436fSMatthias Ringwald 
2911664436fSMatthias Ringwald // block-wise "DMA" RX/TX UART driver
2921664436fSMatthias Ringwald #ifdef __GNUC__
2931664436fSMatthias Ringwald __attribute__((interrupt(USCI_A2_VECTOR)))
2941664436fSMatthias Ringwald #endif
2951664436fSMatthias Ringwald #ifdef __IAR_SYSTEMS_ICC__
2961664436fSMatthias Ringwald #pragma vector=USCI_A2_VECTOR
2971664436fSMatthias Ringwald __interrupt
2981664436fSMatthias Ringwald #endif
usbRxTxISR(void)2991664436fSMatthias Ringwald void usbRxTxISR(void){
3001664436fSMatthias Ringwald 
3011664436fSMatthias Ringwald     // find reason
3021664436fSMatthias Ringwald     switch (UCA2IV){
3031664436fSMatthias Ringwald 
3041664436fSMatthias Ringwald         case 2: // RXIFG
3051664436fSMatthias Ringwald             if (bytes_to_read == 0) {
3061664436fSMatthias Ringwald                 hal_uart_dma_disable_rx();
3071664436fSMatthias Ringwald                 UCA2IE &= ~UCRXIE ;  // disable RX interrupts
3081664436fSMatthias Ringwald                 return;
3091664436fSMatthias Ringwald             }
3101664436fSMatthias Ringwald             *rx_buffer_ptr = UCA2RXBUF;
3111664436fSMatthias Ringwald             ++rx_buffer_ptr;
3121664436fSMatthias Ringwald             --bytes_to_read;
3131664436fSMatthias Ringwald             if (bytes_to_read > 0) {
3141664436fSMatthias Ringwald                 hal_uart_dma_enable_rx();
3151664436fSMatthias Ringwald                 return;
3161664436fSMatthias Ringwald             }
3171664436fSMatthias Ringwald             P1OUT |= BIT4;      // = 1 - RTS high -> stop
3181664436fSMatthias Ringwald             UCA2IE &= ~UCRXIE ; // disable RX interrupts
3191664436fSMatthias Ringwald 
3201664436fSMatthias Ringwald             (*rx_done_handler)();
3211664436fSMatthias Ringwald 
3221664436fSMatthias Ringwald             // force exit low power mode
3231664436fSMatthias Ringwald             __bic_SR_register_on_exit(LPM0_bits);   // Exit active CPU
3241664436fSMatthias Ringwald 
3251664436fSMatthias Ringwald             break;
3261664436fSMatthias Ringwald 
3271664436fSMatthias Ringwald         case 4: // TXIFG
3281664436fSMatthias Ringwald             if (bytes_to_write == 0){
3291664436fSMatthias Ringwald                 UCA2IE &= ~UCTXIE ;  // disable TX interrupts
3301664436fSMatthias Ringwald                 return;
3311664436fSMatthias Ringwald             }
3321664436fSMatthias Ringwald             UCA2TXBUF = *tx_buffer_ptr;
3331664436fSMatthias Ringwald             ++tx_buffer_ptr;
3341664436fSMatthias Ringwald             --bytes_to_write;
3351664436fSMatthias Ringwald 
3361664436fSMatthias Ringwald             if (bytes_to_write > 0) {
3371664436fSMatthias Ringwald                 return;
3381664436fSMatthias Ringwald             }
3391664436fSMatthias Ringwald 
3401664436fSMatthias Ringwald             UCA2IE &= ~UCTXIE ;  // disable TX interrupts
3411664436fSMatthias Ringwald 
3421664436fSMatthias Ringwald             (*tx_done_handler)();
3431664436fSMatthias Ringwald 
3441664436fSMatthias Ringwald             // force exit low power mode
3451664436fSMatthias Ringwald             __bic_SR_register_on_exit(LPM0_bits);   // Exit active CPU
3461664436fSMatthias Ringwald 
3471664436fSMatthias Ringwald             break;
3481664436fSMatthias Ringwald 
3491664436fSMatthias Ringwald         default:
3501664436fSMatthias Ringwald             break;
3511664436fSMatthias Ringwald     }
3521664436fSMatthias Ringwald }
3531664436fSMatthias Ringwald 
3541664436fSMatthias Ringwald 
3551664436fSMatthias Ringwald // CTS ISR
3561664436fSMatthias Ringwald 
3571664436fSMatthias Ringwald extern void ehcill_handle(uint8_t action);
3581664436fSMatthias Ringwald #define EHCILL_CTS_SIGNAL      0x034
3591664436fSMatthias Ringwald 
3601664436fSMatthias Ringwald #ifdef __GNUC__
3611664436fSMatthias Ringwald __attribute__((interrupt(PORT1_VECTOR)))
3621664436fSMatthias Ringwald #endif
3631664436fSMatthias Ringwald #ifdef __IAR_SYSTEMS_ICC__
3641664436fSMatthias Ringwald #pragma vector=PORT1_VECTOR
3651664436fSMatthias Ringwald __interrupt
3661664436fSMatthias Ringwald #endif
ctsISR(void)3671664436fSMatthias Ringwald void ctsISR(void){
3681664436fSMatthias Ringwald     P1IV = 0;
3691664436fSMatthias Ringwald     (*cts_irq_handler)();
3701664436fSMatthias Ringwald }
371