3 * Copyright: (c) 2011 by Peter@Lorenzen.us
4 * License: [BSD]eerware
5 * serput{c,s} sergetc functionality as on UNIX
12 #include "msp430_serial.h"
16 char dlevel = DEBUG_START;
18 char dlevel = DEBUG_LEVEL;
25 fifo_t fiforx0, fifotx0;
26 fifo_t fiforx1, fifotx1;
27 fifo_t *rxfp0; // NULL not in use
28 fifo_t *txfp0; // NULL not in use
29 fifo_t *rxfp1; // NULL not in use
30 fifo_t *txfp1; // NULL not in use
32 void fifo_init(fifo_t * fp)
40 static void fifo_advance(uint8_t * ptr)
42 if (*ptr == (FIFO_SZ - 1)) {
49 static void fifo_wr(fifo_t * fp, char c)
52 _DINT(); // only need to disable tx irq for this stream
58 static uint8_t fifo_rd(fifo_t * fp) // only called if count>0
60 uint8_t c = fp->b[fp->o];
61 _DINT(); // only need to disable tx irq for this stream
68 //http://mspgcc.sourceforge.net/baudrate.html
69 /** TI lauchpad and EZ430/FETUIF with 12MHz crystal */
70 #if (platform == tilaunchpad)
71 uint8_t bauds[6][3] = {
72 {0x68, 0x00, 0x04} // 0 - 12000000Hz 115273bps
73 , {0xE2, 0x04, 0x00} // 1 - 12000000Hz 9600bps
74 , {0x71, 0x02, 0x00} // 2 - 12000000Hz 19200bps
75 , {0x38, 0x01, 0x55} // 3 - 12000000Hz 38400bps
76 , {0xD0, 0x00, 0x4A} // 4 - 12000000Hz 57581bps
77 , {0x68, 0x00, 0x04} // 5 - 12000000Hz 115273bps
80 uint8_t bauds[6][3] = {
81 {0x20, 0x00, 0x00} // 0 - 3683400Hz 115106bps
82 , {0x7F, 0x01, 0x5B} // 1 - 3683400Hz 9599bps
83 , {0xBF, 0x00, 0xF7} // 2 - 3683400Hz 19194bps
84 , {0x5F, 0x00, 0xBF} // 3 - 3683400Hz 38408bps
85 , {0x40, 0x00, 0x00} // 4 - 3683400Hz 57553bps
86 , {0x20, 0x00, 0x00} // 5 - 3683400Hz 115106bps
90 void setbaud0(uint8_t rate)
92 UBR00 = bauds[rate][0];
93 UBR10 = bauds[rate][1];
94 UMCTL0 = bauds[rate][2];
97 void setbaud1(uint8_t rate)
99 UBR01 = bauds[rate][0];
100 UBR11 = bauds[rate][1];
101 UMCTL1 = bauds[rate][2];
104 // we assume rx and tx is always supplied, so no check
105 void ser0_init(int baud, fifo_t * rx, fifo_t * tx)
109 P3DIR &= ~BIT5; // Select P35 for input (UART0RX)
110 P3SEL |= BIT4 | BIT5; // P3.4,5 = USART0 TXD/RXD
113 UCTL0 = SWRST | CHAR; /* 8-bit character, UART mode */
114 ME1 &= ~USPIE0; // USART1 SPI module disable
115 UTCTL0 = SSEL1; /* UCLK = MCLK */
119 ME1 &= ~USPIE0; /* USART1 SPI module disable */
120 ME1 |= (UTXE0 | URXE0); /* Enable USART1 TXD/RXD */
124 //U0TCTL |= URXSE; // XXX Clear pending interrupts before enable!!!
128 IE1 |= UTXIE0; // Enable USART0 TX interrupt
129 IE1 |= URXIE0; // Enable USART0 RX interrupt
132 P1OUT &= ~(DSR | CTS); // We are On and we are ready
135 // we can use uart1 tx for debug messages, using rx bit for something else
136 // or we can use full uart1 for pass through
137 // or not uart1 functions at all,
138 void ser1_init(int baud, fifo_t * rx, fifo_t * tx)
142 if (rx) { // RX enabled
143 P3SEL |= BIT7; // Select P37 for UART1 RX function
144 P3DIR &= ~BIT7; // P37 is input
146 P3SEL &= ~BIT7; // No UART1 RX, can be used as a bit port
148 if (tx) { // TX enabled
149 P3SEL |= BIT6; // Select P36 for UART1 TX function
150 P3DIR |= BIT6; // P36 is output UART1 TX
152 P3SEL &= ~BIT6; // No UART1 TX, can be used as a bit port
154 UCTL1 = SWRST | CHAR; // 8-bit character, UART mode stop UART state machine
155 if (rx || tx) { // RX or TX enabled
156 ME2 &= ~USPIE1; // USART1 SPI module disable
158 UTCTL1 = SSEL1; // UCLK = MCLK
160 //U1TCTL |= URXSE; // XXX Clear pending interrupts before enable!!!
161 if (rx) { // RX enabled
162 ME2 |= URXE1; // Enable USART1 RX
165 if (tx) { // TX enabled
166 ME2 |= UTXE1; // Enable USART1 TXD
170 setbaud1(baud); // we set it even when disabling uart1 - who cares
172 UCTL1 &= ~SWRST; // enable UART state machine
173 if (tx) { // TX enabled
174 IE2 |= UTXIE1; // Enable USART1 TX interrupt
176 IE2 &= ~UTXIE1; // Disable USART1 TX interrupt
178 if (rx) { // RX enabled
179 IE2 |= URXIE1; // Enable USART1 RX interrupt
181 IE2 &= ~URXIE1; // Disable USART1 TX interrupt
186 int seravailable(fifo_t * fp)
191 void serflush(fifo_t * fp)
193 while (seravailable(fp) > 0) {
198 int sergetc(fifo_t * fp)
212 void serclear(fifo_t *fp)
214 while (seravailable(fp) > 0) {
220 // send debug messages over USB-serial link encapsulated in the goodfet protocol
229 void dputs(char *str)
240 debugbytes((char *)&w,2);
243 // defines in msp430_serial.h resolves to the functions below on txfp1
246 void serputc(char c, fifo_t * fp)
250 while (seravailable(fp) == FIFO_SZ) {
252 fifo_wr(fp, c); // magic is in count-- indivisible, do not optimize
253 if (fp->empty && fp->count) { // buffer had been empty
264 void serputs(char *cpt, fifo_t * fp)
274 return i > 9 ? 'a' + i - 10 : '0' + i;
277 void serputb(char c, fifo_t * fp)
279 serputc(hex2c(c>>4), fp);
280 serputc(hex2c(c), fp);
283 void serputw(int w, fifo_t * fp)
286 serputb(w & 0xff, fp);
290 char *dddlog_input(char c)
304 // These is what goodfet uses
308 while (seravailable(rxfp0) == 0) { // wait for data to be available
309 // FIXME we should sleep
312 dddputs(dddlog_input(c));
319 while ((seravailable(rxfp1)) == 0) { // wait for data to be available
320 // FIXME we should sleep
326 void serial0_tx(uint8_t x)
331 void serial1_tx(uint8_t x)
338 interrupt(UART0RX_VECTOR) UART0_RX_ISR(void)
341 rxfp0->b[rxfp0->i] = RXBUF0;
342 fifo_advance(&rxfp0->i);
346 interrupt(UART1RX_VECTOR) UART1_RX_ISR(void)
349 rxfp1->b[rxfp1->i] = RXBUF1;
350 fifo_advance(&rxfp1->i);
354 interrupt(UART0TX_VECTOR) UART0_TX_ISR(void)
357 TXBUF0 = txfp0->b[txfp0->o];
358 fifo_advance(&txfp0->o);
365 interrupt(UART1TX_VECTOR) UART1_TX_ISR(void)
368 TXBUF1 = txfp1->b[txfp1->o];
369 fifo_advance(&txfp1->o);