Because some interrupts share an interrupt vector, we use the relevant interrupt
enable bit to decide if any user is interested in the interrupt. If not, that
interrupt is skipped so that another interrupt in the if/then/elseif chain can
be taken. We also defensively try to prevent I2C interrupts from being a
problem if not used, although no I2C code using these interrupts has yet been
written.
* 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))
+ } else if (READ_FLAG(UC0IFG & UC0IE, UCB0RXIE)) {
signal IntB.rx(UCB0RXBUF); /* read clears UCB0RXIFG */
- else if (READ_FLAG(UCB0STAT, UCALIFG))
+
+ /* 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 interrupt vector signals transmit events. USCI_A0 can receive events
* 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();
}
* modes.
*/
TOSH_SIGNAL(USCIAB1RX_VECTOR) {
- if (READ_FLAG(UC1IFG, UCA1RXIFG)) {
+ if (READ_FLAG(UC1IFG & UC1IE, UCA1RXIE)) {
volatile uint8_t c = UCA1RXBUF; /* read to clear UCA1RXIFG */
if (READ_FLAG(UCA1CTL1, UCBRK)) {
- UCA1CTL1 &= ~UCBRK;
+ CLR_FLAG(UCA1CTL1, UCBRK);
if (READ_FLAG(UCA1CTL0, UCMODE_3) == UCMODE_3)
- UCA1CTL1 &= ~UCDORM;
+ CLR_FLAG(UCA1CTL1, UCDORM);
signal IntA.brk();
} else
signal IntA.rx(c);
- } else if (READ_FLAG(UC1IFG, UCB1RXIFG))
+ } else if (READ_FLAG(UC1IFG & UC1IE, UCB1RXIE)) {
signal IntB.rx(UCB1RXBUF); /* read clears UCB1RXIFG */
- else if (READ_FLAG(UCB1STAT, UCALIFG))
+
+ /* 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(UCB1STAT, UCALIFG)) {
+ CLR_FLAG(UCB1STAT, UCALIFG);
signal IntB.i2cCal();
- else if (READ_FLAG(UCB1STAT, UCNACKIFG))
+ } else if (READ_FLAG(UCB1STAT, UCNACKIFG)) {
+ CLR_FLAG(UCB1STAT, UCNACKIFG);
+ CLR_FLAG(UC1IFG, UCB1TXIFG); /* Errata USCI25; 'reset' means clear? */
signal IntB.i2cNak();
- else if (READ_FLAG(UCB1STAT, UCSTTIFG))
+ } else if (READ_FLAG(UCB1STAT, UCSTTIFG)) {
+ CLR_FLAG(UCB1STAT, UCSTTIFG);
signal IntB.i2cStart();
- else if (READ_FLAG(UCB1STAT, UCSTPIFG))
+ } else if (READ_FLAG(UCB1STAT, UCSTPIFG)) {
+ CLR_FLAG(UCB1STAT, UCSTPIFG);
signal IntB.i2cStop();
+ }
}
/* This interrupt vector signals transmit events. USCI_A1 can receive events
* modes.
*/
TOSH_SIGNAL(USCIAB1TX_VECTOR) {
- if (READ_FLAG(UC1IFG, UCB1RXIFG))
+ if (READ_FLAG(UC1IFG & UC1IE, UCB1RXIE))
signal IntB.rx(UCB1RXBUF); /* I2C receive */
- else if (READ_FLAG(UC1IFG, UCA1TXIFG))
+ else if (READ_FLAG(UC1IFG & UC1IE, UCA1TXIFG))
signal IntA.tx();
- else if (READ_FLAG(UC1IFG, UCB1TXIFG))
+ else if (READ_FLAG(UC1IFG & UC1IE, UCB1TXIFG))
signal IntB.tx();
}