X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Fmsp430%2Fusci%2FHplMsp430UsciInt0P.nc;h=9e69649cd7701f039c4fa3e132a562e394d956bd;hb=59a38cc43b09cc83e1a414ec0531588abab72cc9;hp=8c3a34510f789fed01a2a6095b996ccc6abc0eae;hpb=b054fbe2a8deacc35f0067deb15274da53d96984;p=tinyos-2.x.git diff --git a/tos/chips/msp430/usci/HplMsp430UsciInt0P.nc b/tos/chips/msp430/usci/HplMsp430UsciInt0P.nc index 8c3a3451..9e69649c 100644 --- a/tos/chips/msp430/usci/HplMsp430UsciInt0P.nc +++ b/tos/chips/msp430/usci/HplMsp430UsciInt0P.nc @@ -62,47 +62,55 @@ implementation MSP430REG_NORACE(UCB0RXBUF); #endif - /* This USCI_Ax and USCI_Bx interrupt vector signals receive events for UART - * and SPI modes, and status events for I2C modes. Only Bx can do I2C. + /* This interrupt vector signals receive events. USCI_A0 can receive events + * for UART and SPI modes, while USCI_B0 can receive events for I2C and SPI + * modes. */ TOSH_SIGNAL(USCIAB0RX_VECTOR) { - if (READ_FLAG(UC0IFG, UCA0RXIFG)) { + if (READ_FLAG(UC0IFG & UC0IE, UCA0RXIE)) { volatile uint8_t c = UCA0RXBUF; /* read to clear UCA0RXIFG */ if (READ_FLAG(UCA0CTL1, UCBRK)) { - UCA0CTL1 &= ~UCBRK; + CLR_FLAG(UCA0CTL1, UCBRK); if (READ_FLAG(UCA0CTL0, UCMODE_3) == UCMODE_3) - UCA0CTL1 &= ~UCDORM; + CLR_FLAG(UCA0CTL1, UCDORM); signal IntA.brk(); } else signal IntA.rx(c); - } else if (READ_FLAG(UC0IFG, UCB0RXIFG)) { - volatile uint8_t c = UCB0RXBUF; /* read to clear UCB0RXIFG */ - if (READ_FLAG(UCB0CTL1, UCBRK)) { - CLR_FLAG(UCB0CTL1, UCBRK); - if (READ_FLAG(UCB0CTL0, UCMODE_3) == UCMODE_3) - CLR_FLAG(UCB0CTL1, UCDORM); - signal IntB.brk(); - } else - signal IntB.rx(c); - } else if (READ_FLAG(UCB0STAT, UCALIFG)) + } else if (READ_FLAG(UC0IFG & UC0IE, UCB0RXIE)) { + signal IntB.rx(UCB0RXBUF); /* read clears UCB0RXIFG */ + + /* FIXME: the arbitration of I2C interrupts are not vetted. If, for example + * the UCALIFG bit gets set and neither it nor the corresponding interrupt + * enable bit is never unset, then an ISR configured for UCSTTIFG or + * UCSTPIFG will never be signalled. + */ + + } else if (READ_FLAG(UCB0STAT, UCALIFG)) { + CLR_FLAG(UCB0STAT, UCALIFG); signal IntB.i2cCal(); - else if (READ_FLAG(UCB0STAT, UCNACKIFG)) + } else if (READ_FLAG(UCB0STAT, UCNACKIFG)) { + CLR_FLAG(UCB0STAT, UCNACKIFG); + CLR_FLAG(UC0IFG, UCB0TXIFG); /* Errata USCI25; 'reset' means clear? */ signal IntB.i2cNak(); - else if (READ_FLAG(UCB0STAT, UCSTTIFG)) + } else if (READ_FLAG(UCB0STAT, UCSTTIFG)) { + CLR_FLAG(UCB0STAT, UCSTTIFG); signal IntB.i2cStart(); - else if (READ_FLAG(UCB0STAT, UCSTPIFG)) + } else if (READ_FLAG(UCB0STAT, UCSTPIFG)) { + CLR_FLAG(UCB0STAT, UCSTPIFG); signal IntB.i2cStop(); + } } - /* This USCI_Ax and USCI_Bx interrupt vector signals transmit events for UART - * and SPI modes, and rx/tx events for I2C modes. Only Bx can do I2C. + /* This interrupt vector signals transmit events. USCI_A0 can receive events + * for UART and SPI modes, while USCI_B0 can receive events for I2C and SPI + * modes. */ TOSH_SIGNAL(USCIAB0TX_VECTOR) { - if (READ_FLAG(UC0IFG, UCB0RXIFG)) + if (READ_FLAG(UC0IFG & UC0IE, UCB0RXIE)) signal IntB.rx(UCB0RXBUF); /* I2C receive */ - else if (READ_FLAG(UC0IFG, UCA0TXIFG)) + else if (READ_FLAG(UC0IFG & UC0IE, UCA0TXIFG)) signal IntA.tx(); - else if (READ_FLAG(UC0IFG, UCB0TXIFG)) + else if (READ_FLAG(UC0IFG & UC0IE, UCB0TXIFG)) signal IntB.tx(); } @@ -115,6 +123,7 @@ implementation default async event void IntA.i2cStart() {} default async event void IntA.i2cStop() {} + /* UART is not available for B devices, so IntB.brk() is never sitnalled */ default async event void IntB.brk() {} default async event void IntB.rx(uint8_t byte) {} default async event void IntB.tx() {}