|  | /* | 
|  | *  ======== SysUart.c ======== | 
|  | */ | 
|  | #include <xdc/runtime/Startup.h> | 
|  |  | 
|  | #include "package/internal/SysUart.xdc.h" | 
|  |  | 
|  | #define USE_8MHZ    1 | 
|  |  | 
|  | #define RED         0x01 | 
|  | #define GREEN       0x02 | 
|  |  | 
|  | #define FOREVER     -1 | 
|  |  | 
|  | static void etx(); | 
|  | static void flash(Int color, Int period, Int count); | 
|  | static void init(void); | 
|  | static void myPutc(Char ch); | 
|  |  | 
|  | /* | 
|  | *  ======== SysUart_Module_startup ======== | 
|  | */ | 
|  | Int SysUart_Module_startup(Int state) | 
|  | { | 
|  | init(); | 
|  | return (Startup_DONE); | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== SysUart_abort ======== | 
|  | */ | 
|  | Void SysUart_abort(String str) | 
|  | { | 
|  | if (str != NULL) { | 
|  | Char ch; | 
|  |  | 
|  | while ((ch = *str++) != '\0') { | 
|  | SysUart_putch(ch); | 
|  | } | 
|  | } | 
|  | flash(RED, FOREVER, FOREVER); | 
|  | etx(); | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== SysUart_exit ======== | 
|  | */ | 
|  | Void SysUart_exit(Int stat) | 
|  | { | 
|  | flash(GREEN, FOREVER, FOREVER); | 
|  | etx(); | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== SysUart_flush ======== | 
|  | */ | 
|  | Void SysUart_flush() | 
|  | { | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== SysUart_putch ======== | 
|  | */ | 
|  | Void SysUart_putch(Char ch) | 
|  | { | 
|  | myPutc(ch); | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== SysUart_ready ======== | 
|  | */ | 
|  | Bool SysUart_ready() | 
|  | { | 
|  | return (TRUE); | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== atexit ======== | 
|  | *  The TI RTS library's atexit() implementation requires a _huge_ amount of | 
|  | *  data.  We stub it out here and replace exit() and abort() with functions | 
|  | *  that are sufficient for the proper operation of xdc.runtime.System. | 
|  | */ | 
|  | int atexit(void (*fxn)(void)) | 
|  | { | 
|  | return (0); | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== abort ======== | 
|  | *  See atexit() above | 
|  | */ | 
|  | void abort(void) | 
|  | { | 
|  | /*  Define C$$EXIT label because TI debugger uses this to know when | 
|  | *  programs terminate.  This can be removed if the debugger is not | 
|  | *  used. | 
|  | */ | 
|  | __asm("        .global C$$EXIT"); | 
|  | __asm("C$$EXIT: nop"); | 
|  |  | 
|  | for (;;);   /* spin forever */ | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== exit ======== | 
|  | *  See atexit() above | 
|  | */ | 
|  | void exit(int status) | 
|  | { | 
|  | SysUart_exit(status); | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== etx ======== | 
|  | *  Flush HW TX buffers | 
|  | */ | 
|  | static void etx() | 
|  | { | 
|  | myPutc(4);  /* ascii EOT */ | 
|  | myPutc(0); | 
|  | myPutc(0); | 
|  | abort(); | 
|  | } | 
|  |  | 
|  | #if 0 | 
|  | /* standard header assumes linker command file definitions */ | 
|  | #include  <ti/apps/msp430/msp430x22x4.h> | 
|  | #else | 
|  | /* "pure-C" definitions below are sufficient for this module */ | 
|  | #define IE2        (*(volatile int8_t *)0x0001)   /* 8-bit */ | 
|  | #define IFG2       (*(volatile int8_t *)0x0003)   /* 8-bit */ | 
|  |  | 
|  | #define DCOCTL     (*(volatile int8_t *)0x0056)   /* 8-bit */ | 
|  | #define BCSCTL1    (*(volatile int8_t *)0x0057)   /* 8-bit */ | 
|  | #define BCSCTL3    (*(volatile int8_t *)0x0053)   /* 8-bit */ | 
|  |  | 
|  | #define CALDCO_8MHZ (*(volatile int8_t *)0x10FC)  /* 8-bit */ | 
|  | #define CALBC1_8MHZ (*(volatile int8_t *)0x10FD)  /* 8-bit */ | 
|  |  | 
|  | #define P1OUT      (*(volatile int8_t *)0x0021)   /* 8-bit */ | 
|  | #define P1DIR      (*(volatile int8_t *)0x0022)   /* 8-bit */ | 
|  | #define P3SEL      (*(volatile int8_t *)0x001B)   /* 8-bit */ | 
|  |  | 
|  | #define UCA0CTL1   (*(volatile int8_t *)0x0061)   /* 8-bit */ | 
|  | #define UCA0BR0    (*(volatile int8_t *)0x0062)   /* 8-bit */ | 
|  | #define UCA0BR1    (*(volatile int8_t *)0x0063)   /* 8-bit */ | 
|  | #define UCA0MCTL   (*(volatile int8_t *)0x0064)   /* 8-bit */ | 
|  | #define UCA0RXBUF  (*(volatile int8_t *)0x0066)   /* 8-bit */ | 
|  | #define UCA0TXBUF  (*(volatile int8_t *)0x0067)   /* 8-bit */ | 
|  |  | 
|  | #define WDTCTL     (*(volatile int16_t *)0x120)   /* 16-bit */ | 
|  |  | 
|  | /* status register bits */ | 
|  | #define GIE        (0x0008) | 
|  | #define CPUOFF     (0x0010) | 
|  |  | 
|  | #define LPM0_bits  (CPUOFF) | 
|  |  | 
|  | /* watch dog timer control register bit names */ | 
|  | #define WDTPW       (0x5A00) | 
|  | #define WDTHOLD     (0x0080) | 
|  |  | 
|  | #define LFXT1S_2    (0x20)      /* Mode 2 for LFXT1 : VLO */ | 
|  |  | 
|  | #define UCSSEL_2    (0x80)      /* USCI 0 Clock Source: 2 */ | 
|  | #define UCBRS_2      (0x04)      /* USCI Second Stage Modulation Select 1 */ | 
|  | #define UCSWRST     (0x01)      /* USCI Software Reset */ | 
|  | #define UCA0RXIE    (0x01)      /* USCI rx interrupt enable */ | 
|  |  | 
|  | /* IFG2 bits */ | 
|  | #define UCA0TXIFG   (0x02)      /* USCI tx flag bit */ | 
|  | #endif | 
|  |  | 
|  | /* | 
|  | *  ======== init ======== | 
|  | */ | 
|  | static void init(void) | 
|  | { | 
|  | WDTCTL = WDTPW + WDTHOLD;       /* Stop watchdog timer */ | 
|  |  | 
|  | P1DIR |= 0x03;                  /* Set P1.0,1 to output direction */ | 
|  | P1OUT = 0;                      /* turn off LEDs */ | 
|  |  | 
|  | #if USE_8MHZ | 
|  | BCSCTL1 = CALBC1_8MHZ;          /* Set DCO to the default of Simpliciti */ | 
|  | DCOCTL = CALDCO_8MHZ; | 
|  | BCSCTL3 |= LFXT1S_2;            /* LFXT1 = VLO */ | 
|  | #else | 
|  | BCSCTL1 = CALBC1_1MHZ;          /* Set DCO to 1MHz */ | 
|  | DCOCTL = CALDCO_1MHZ; | 
|  | #endif | 
|  |  | 
|  | /* init the UART (see Table 15-4, Section 15.3.13 MSP430 User's guide) */ | 
|  | P3SEL = 0x30;           /* P3.4,5 = USCI_A0 TXD/RXD */ | 
|  | UCA0CTL1 = UCSSEL_2;    /* SMCLK */ | 
|  | #if USE_8MHZ | 
|  | UCA0BR0 = 0x41;         /* 8MHz DCO 9600 (UCBRx = 833) */ | 
|  | UCA0BR1 = 0x03;         /* 8MHz DC0 9600 */ | 
|  | UCA0MCTL = UCBRS_2;     /* 8MHz DC0 Modulation (UCBRSx = 2: UCOS16 = 0, UCBRFx = 0) */ | 
|  | #else | 
|  | UCA0BR0 = 104;          /* 1MHz DC0 9600 (@8MHz 9600, use 0x41) */ | 
|  | UCA0BR1 = 0;            /* 1MHz DC0 9600 (@8MHz 9600, use 0x03) */ | 
|  | UCA0MCTL = UCBRS0;      /* 1MHz DC0 Modulation (UCBRSx = 1: UCOS16 = 0, UCBRFx = 0) */ | 
|  | #endif | 
|  |  | 
|  | UCA0CTL1 &= ~UCSWRST;   /* Initialize USCI state machine */ | 
|  | IE2 |= UCA0RXIE;        /* Enable USCI_A0 RX interrupt */ | 
|  |  | 
|  | flash(GREEN, 50, 4);    /* indicate the init is done */ | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== flash ======== | 
|  | */ | 
|  | static void flash(Int color, Int period, Int count) | 
|  | { | 
|  | if (period == FOREVER) { | 
|  | P1OUT |= color; | 
|  | return; | 
|  | } | 
|  |  | 
|  | while (count) { | 
|  | volatile unsigned int i;    /* volatile to prevent optimization */ | 
|  |  | 
|  | P1OUT ^= color;             /* toggle P1.1,0 using exclusive-OR */ | 
|  |  | 
|  | for (i = period * 1000; i != 0; i--) {  /* delay period */ | 
|  | ; | 
|  | } | 
|  |  | 
|  | if (count > 0) {            /* if count starts < 0, go forever */ | 
|  | count--; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== myPutc ======== | 
|  | */ | 
|  | static void myPutc(Char ch) | 
|  | { | 
|  | while (!(IFG2 & UCA0TXIFG)) {   /* USCI_A0 TX buffer ready? */ | 
|  | ; | 
|  | } | 
|  |  | 
|  | UCA0TXBUF = ch;                 /* TX -> ch */ | 
|  | } | 
|  |  | 
|  | /* | 
|  | *  ======== USCI0RX_ISR ======== | 
|  | */ | 
|  | __interrupt void USCI0RX_ISR(void) | 
|  | { | 
|  | char c; | 
|  |  | 
|  | c = UCA0RXBUF;                  /* read the character */ | 
|  |  | 
|  | if (SysUart_getLineFxn == NULL) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (SysUart_lineBuf == NULL) { | 
|  | SysUart_getLineFxn(&c, 1); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (c == '\n') { | 
|  | SysUart_lineBuf[module->lineIdx] = 0; | 
|  | SysUart_getLineFxn(SysUart_lineBuf, module->lineIdx); | 
|  | module->lineIdx = 0; | 
|  | } | 
|  | else if (module->lineIdx < SysUart_lineSize) { | 
|  | SysUart_lineBuf[module->lineIdx++] = c; | 
|  | } | 
|  | } | 
|  |  | 
|  | __asm("\t.global USCI0RX_ISR"); | 
|  | __asm("\t.sect   \".usci_rx\""); | 
|  | __asm("\t.align  2"); | 
|  | __asm("_USCI0_rx_vector:\n\t.field USCI0RX_ISR, 16"); |