]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/msp430/usci/HplMsp430UsciInt1P.nc
Improve interrupt handling for USCI.
[tinyos-2.x.git] / tos / chips / msp430 / usci / HplMsp430UsciInt1P.nc
index 5fa0291ca8255daaa7a2f7fbc11c28afb78b1862..2b9b1d4fa052a57766677ff98330b624e1ecc5ea 100644 (file)
@@ -60,25 +60,38 @@ implementation
    * 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
@@ -86,11 +99,11 @@ implementation
    * 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();
   }