3 * Copyright: (c) 2011 by Peter@Lorenzen.us
4 * License: [BSD]eerware
5 * serput{c,s} sergetc functionality as on UNIX
8 //FIXME This should switch to the standard GoodFET functions for the msp430f161x chips.
14 #include "msp430_serial.h"
18 char dlevel = DEBUG_START;
20 char dlevel = DEBUG_LEVEL;
27 fifo_t fiforx0, fifotx0;
28 fifo_t fiforx1, fifotx1;
29 fifo_t *rxfp0; // NULL not in use
30 fifo_t *txfp0; // NULL not in use
31 fifo_t *rxfp1; // NULL not in use
32 fifo_t *txfp1; // NULL not in use
34 void fifo_init(fifo_t * fp)
42 static void fifo_advance(uint8_t * ptr)
44 if (*ptr == (FIFO_SZ - 1)) {
51 static void fifo_wr(fifo_t * fp, char c)
54 _DINT(); // only need to disable tx irq for this stream
60 static uint8_t fifo_rd(fifo_t * fp) // only called if count>0
62 uint8_t c = fp->b[fp->o];
63 _DINT(); // only need to disable tx irq for this stream
70 //http://mspgcc.sourceforge.net/baudrate.html
71 /** TI lauchpad and EZ430/FETUIF with 12MHz crystal */
72 #if (platform == tilaunchpad)
73 uint8_t bauds[6][3] = {
74 {0x68, 0x00, 0x04} // 0 - 12000000Hz 115273bps
75 , {0xE2, 0x04, 0x00} // 1 - 12000000Hz 9600bps
76 , {0x71, 0x02, 0x00} // 2 - 12000000Hz 19200bps
77 , {0x38, 0x01, 0x55} // 3 - 12000000Hz 38400bps
78 , {0xD0, 0x00, 0x4A} // 4 - 12000000Hz 57581bps
79 , {0x68, 0x00, 0x04} // 5 - 12000000Hz 115273bps
82 uint8_t bauds[6][3] = {
83 {0x20, 0x00, 0x00} // 0 - 3683400Hz 115106bps
84 , {0x7F, 0x01, 0x5B} // 1 - 3683400Hz 9599bps
85 , {0xBF, 0x00, 0xF7} // 2 - 3683400Hz 19194bps
86 , {0x5F, 0x00, 0xBF} // 3 - 3683400Hz 38408bps
87 , {0x40, 0x00, 0x00} // 4 - 3683400Hz 57553bps
88 , {0x20, 0x00, 0x00} // 5 - 3683400Hz 115106bps
92 void setbaud0(uint8_t rate)
94 UBR00 = bauds[rate][0];
95 UBR10 = bauds[rate][1];
96 UMCTL0 = bauds[rate][2];
99 void setbaud1(uint8_t rate)
101 UBR01 = bauds[rate][0];
102 UBR11 = bauds[rate][1];
103 UMCTL1 = bauds[rate][2];
106 // we assume rx and tx is always supplied, so no check
107 void ser0_init(int baud, fifo_t * rx, fifo_t * tx)
111 P3DIR &= ~BIT5; // Select P35 for input (UART0RX)
112 P3SEL |= BIT4 | BIT5; // P3.4,5 = USART0 TXD/RXD
115 UCTL0 = SWRST | CHAR; /* 8-bit character, UART mode */
116 ME1 &= ~USPIE0; // USART1 SPI module disable
117 UTCTL0 = SSEL1; /* UCLK = MCLK */
121 ME1 &= ~USPIE0; /* USART1 SPI module disable */
122 ME1 |= (UTXE0 | URXE0); /* Enable USART1 TXD/RXD */
126 //U0TCTL |= URXSE; // XXX Clear pending interrupts before enable!!!
130 IE1 |= UTXIE0; // Enable USART0 TX interrupt
131 IE1 |= URXIE0; // Enable USART0 RX interrupt
134 P1OUT &= ~(DSR | CTS); // We are On and we are ready
137 // we can use uart1 tx for debug messages, using rx bit for something else
138 // or we can use full uart1 for pass through
139 // or not uart1 functions at all,
140 void ser1_init(int baud, fifo_t * rx, fifo_t * tx)
144 if (rx) { // RX enabled
145 P3SEL |= BIT7; // Select P37 for UART1 RX function
146 P3DIR &= ~BIT7; // P37 is input
148 P3SEL &= ~BIT7; // No UART1 RX, can be used as a bit port
150 if (tx) { // TX enabled
151 P3SEL |= BIT6; // Select P36 for UART1 TX function
152 P3DIR |= BIT6; // P36 is output UART1 TX
154 P3SEL &= ~BIT6; // No UART1 TX, can be used as a bit port
156 UCTL1 = SWRST | CHAR; // 8-bit character, UART mode stop UART state machine
157 if (rx || tx) { // RX or TX enabled
158 ME2 &= ~USPIE1; // USART1 SPI module disable
160 UTCTL1 = SSEL1; // UCLK = MCLK
162 //U1TCTL |= URXSE; // XXX Clear pending interrupts before enable!!!
163 if (rx) { // RX enabled
164 ME2 |= URXE1; // Enable USART1 RX
167 if (tx) { // TX enabled
168 ME2 |= UTXE1; // Enable USART1 TXD
172 setbaud1(baud); // we set it even when disabling uart1 - who cares
174 UCTL1 &= ~SWRST; // enable UART state machine
175 if (tx) { // TX enabled
176 IE2 |= UTXIE1; // Enable USART1 TX interrupt
178 IE2 &= ~UTXIE1; // Disable USART1 TX interrupt
180 if (rx) { // RX enabled
181 IE2 |= URXIE1; // Enable USART1 RX interrupt
183 IE2 &= ~URXIE1; // Disable USART1 TX interrupt
188 int seravailable(fifo_t * fp)
193 void serflush(fifo_t * fp)
195 while (seravailable(fp) > 0) {
200 int sergetc(fifo_t * fp)
214 void serclear(fifo_t *fp)
216 while (seravailable(fp) > 0) {
222 // send debug messages over USB-serial link encapsulated in the goodfet protocol
231 void dputs(char *str)
242 debugbytes((char *)&w,2);
245 // defines in msp430_serial.h resolves to the functions below on txfp1
248 void serputc(char c, fifo_t * fp)
252 while (seravailable(fp) == FIFO_SZ) {
254 fifo_wr(fp, c); // magic is in count-- indivisible, do not optimize
255 if (fp->empty && fp->count) { // buffer had been empty
266 void serputs(char *cpt, fifo_t * fp)
276 return i > 9 ? 'a' + i - 10 : '0' + i;
279 void serputb(char c, fifo_t * fp)
281 serputc(hex2c(c>>4), fp);
282 serputc(hex2c(c), fp);
285 void serputw(int w, fifo_t * fp)
288 serputb(w & 0xff, fp);
292 char *dddlog_input(char c)
306 // These is what goodfet uses
310 while (seravailable(rxfp0) == 0) { // wait for data to be available
311 // FIXME we should sleep
314 dddputs(dddlog_input(c));
321 while ((seravailable(rxfp1)) == 0) { // wait for data to be available
322 // FIXME we should sleep
328 void serial0_tx(uint8_t x)
333 void serial1_tx(uint8_t x)
340 interrupt(UART0RX_VECTOR) UART0_RX_ISR(void)
343 rxfp0->b[rxfp0->i] = RXBUF0;
344 fifo_advance(&rxfp0->i);
348 interrupt(UART1RX_VECTOR) UART1_RX_ISR(void)
351 rxfp1->b[rxfp1->i] = RXBUF1;
352 fifo_advance(&rxfp1->i);
356 interrupt(UART0TX_VECTOR) UART0_TX_ISR(void)
359 TXBUF0 = txfp0->b[txfp0->o];
360 fifo_advance(&txfp0->o);
367 interrupt(UART1TX_VECTOR) UART1_TX_ISR(void)
370 TXBUF1 = txfp1->b[txfp1->o];
371 fifo_advance(&txfp1->o);