diff --git a/ports/MSP430/msp430_serial.c b/ports/MSP430/msp430_serial.c index 10512a283..26531ebbf 100644 --- a/ports/MSP430/msp430_serial.c +++ b/ports/MSP430/msp430_serial.c @@ -95,13 +95,79 @@ void SetUSART0I(uint16_t div, uint8_t mod, uint8_t ctl) { (void)U0RXBUF; U0RCTL = 0; /* USART enable */ - P3SEL |= BV(4) + BV(5); /* I/O pins for USART */ + P3SEL |= BV(4) + BV(5); /* I/O pins for USART 0 */ U0ME |= UTXE0 + URXE0; /* Enables the USART */ U0CTL = ctl & ~SWRST; /* Various settings, clears reset state */ U0IE |= URXIE0; /* Enables RX interrupt */ } #endif /* USE_MSP430_USART0 */ +#ifdef USE_MSP430_USART1 +FullDuplexDriver COM2; +static uint8_t ib2[SERIAL_BUFFERS_SIZE]; +static uint8_t ob2[SERIAL_BUFFERS_SIZE]; + +interrupt(USART1TX_VECTOR) u1txirq(void) { + msg_t b; + + chSysIRQEnterI(); + + b = chFDDRequestDataI(&COM2); + if (b < Q_OK) + U1IE &= ~UTXIE1; + else + U1TXBUF = b; + + chSysIRQExitI(); +} + +interrupt(USART1RX_VECTOR) u1rxirq(void) { + uint8_t urctl; + + chSysIRQEnterI(); + + if ((urctl = U1RCTL) & RXERR) + SetError(urctl, &COM2); + chFDDIncomingDataI(&COM2, U1RXBUF); + + chSysIRQExitI(); +} + + +/* + * Invoked by the high driver when one or more bytes are inserted in the + * output queue. + */ +static void OutNotify2(void) { + + if (!(U1IE & UTXIE1)) + U1TXBUF = (uint8_t)chFDDRequestDataI(&COM2); + U1IE |= UTXIE1; +} + +/* + * USART setup, must be invoked with interrupts disabled. + * NOTE: Does not reset I/O queues. + */ +void SetUSART1I(uint16_t div, uint8_t mod, uint8_t ctl) { + + U1CTL = SWRST; /* Resets the USART, it should already be */ + /* USART init */ + U1TCTL = SSEL0 | SSEL1; /* SMCLK as clock source */ + U1MCTL = mod; /* Modulator */ + U1BR1 = (uint8_t)(div >> 8); /* Divider high */ + U1BR0 = (uint8_t)(div >> 0); /* Divider low */ + /* Clear USART status */ + (void)U0RXBUF; + U1RCTL = 0; + /* USART enable */ + P3SEL |= BV(6) + BV(7); /* I/O pins for USART 1 */ + U1ME |= UTXE0 + URXE0; /* Enables the USART */ + U1CTL = ctl & ~SWRST; /* Various settings, clears reset state */ + U1IE |= URXIE0; /* Enables RX interrupt */ +} +#endif + void InitSerial(void) { /* I/O queues setup.*/ @@ -111,5 +177,7 @@ void InitSerial(void) { #endif #ifdef USE_MSP430_USART1 + chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2); + SetUSART1I(UBR(38400), 0, CHAR); #endif }