]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/msp430/usci/Msp430UartP.nc
Fix up atomic warnings for robug in MSp430UartP.nc.
[tinyos-2.x.git] / tos / chips / msp430 / usci / Msp430UartP.nc
index b9f25ede5d067e14023063832864e402f6dec9ca..355820460eb6af580b6b211cb13c160596f1cbcd 100644 (file)
@@ -42,10 +42,10 @@ generic module Msp430UartP() {
   uses {
     interface HplMsp430UsciReg as Registers;
     interface HplMsp430UsciInt as Interrupts;
-    interface HplMsp430GeneralIO as RXD; /* Msp430Gpio no access to PxREN */
+    interface HplMsp430GeneralIO as RXD;
     interface HplMsp430GeneralIO as TXD;
-    interface Msp430UsciUartConfigure; /* maybe just Msp430UsciConfigure */
-    interface Counter<T32khz,uint16_6>
+    interface AsyncConfigure<const msp430_usci_uart_t*> as Configure;
+    interface Counter<T32khz,uint16_t>;
     interface ArbiterInfo;
   }
 }
@@ -87,43 +87,99 @@ implementation {
   uint8_t* rbuf; /* Position of next byte in which to receive a char */
   uint8_t rlen; /* Remaining length in receive buffer */
 
-  async command void ResourceConfigure.configure();
+  async command void ResourceConfigure.configure()
   {
-    call Registers.setCtl0(UCSYNC);
-    /* Save pin states */
-    dir = out = ren = 0;
-    saveBits(RXD, 0, dir, out, ren);
-    saveBits(TXD, 1, dir, out, ren);
-    /* FIXME: use Msp430UsciConfig to configure ports */
-    /* FIXME: we may need to have REN/DIR stuff in the configuration... */
-    call RXD.selectModuleFunc();
-    call TXD.selectModuleFunc();
-    /* Clear interrupts; we'll add them as needed */
-    call Registers.clrCtl1(UCRXEIE|UCBRKIE);
-    call Registers.clrIeRx();
-    call Registers.clrIeTx();
-    /* Enable the device */
-    call Registers.clrCtl0(UCSYNC);
+    atomic {
+      const msp430_usci_uart_t* config = call Configure.get();
+
+      call Registers.setCtl1(UCSWRST);
+
+      /* Configure USCI registers */
+      call Registers.assignCtl0(config->ctl0 & ~UCSYNC);
+      call Registers.assignCtl1(config->ctl1 | UCSWRST);
+      call Registers.assignBr0(config->brx & 0xff);
+      call Registers.assignBr1(config->brx >> 8);
+      call Registers.assignMctl(config->mctl);
+      call Registers.assignIrtctl(config->irtctl);
+      call Registers.assignIrrctl(config->irrctl);
+      call Registers.assignAbctl(config->abctl);
+      call Registers.clrStat(UCLISTEN);
+
+      /* Save pin IO states */
+      dir = out = ren = 0;
+      saveBits(RXD, 0, dir, out, ren);
+      saveBits(TXD, 1, dir, out, ren);
+
+      /* Configure RX pin for UART use */
+      call RXD.makeInput();
+      if (config->ren & USCI_REN_RX) {
+       if (config->ren & USCI_REN_RX_PULLUP)
+         call RXD.set();
+       else
+         call RXD.clr();
+       call RXD.enableRen();
+      }
+      call RXD.selectModuleFunc();
+
+#if 0 /* pull-ups don't make sense on TXD, since it doesn't appear that
+       * enabling an open-drain emulation mode via USCI is possible.
+       */
+
+      /* Configure TX pin for UART use */
+      if (config->ren & USCI_REN_TX) {
+       if (config->ren & USCI_REN_TX_PULLUP)
+         call TXD.set();
+       else
+         call TXD.clr();
+       call TXD.enableRen();
+      }
+      call TXD.selectModuleFunc();
+#endif
+
+      /* Clear interrupts; we'll add them as needed */
+      call Registers.clrIeRx();
+      call Registers.clrIeTx();
+
+      /* Enable the device */
+      call Registers.clrCtl1(UCSWRST);
+    }
   }
 
-  async command void ResourceConfigure.unconfigure();
+  async command void ResourceConfigure.unconfigure()
   {
-    /* Disable the device */
-    call Registers.setCtl0(UCSYNC);
-    /* Clear interrupts and interrupt flags */
-    call Registers.clrIeRx();
-    call Registers.clrIeTx();
-    call Registers.clrIfgRx();
-    call Registers.clrIfgTx();
-    /* Restore pins to state just before configure() */
-    restoreBits(RXD, 0, dir, out, ren);
-    restoreBits(TXD, 0, dir, out, ren);
-    call RXD.selectIOFunc();
-    call TXD.selectIOFunc();
+    atomic {
+      /* Disable the device */
+      call Registers.setCtl1(UCSYNC);
+
+      /* Clear interrupts and interrupt flags */
+      call Registers.clrIeRx();
+      call Registers.clrIeTx();
+      call Registers.clrIfgRx();
+      call Registers.clrIfgTx();
+
+      /* Restore pins to their preconfigured state */
+#if 0
+      restoreBits(RXD, 0, dir, out, ren);
+      restoreBits(TXD, 0, dir, out, ren);
+#endif
+      call RXD.selectIOFunc();
+      call TXD.selectIOFunc();
+    }
   }
 
+  async command error_t UartByte.send(uint8_t byte)
+  {
+    /* FIXME: race with UartStream.send() */
+    atomic {
+      if (sobuf)
+       return FAIL;
+      while (call Registers.getStat(UCBUSY));
+      call Registers.setTxbuf(byte);
+      return SUCCESS;
+    }
+  }
 
-  async command error_t UartStream.send( uint8_t* buf, uint16_t len )
+  async command error_t UartStream.send(uint8_t* buf, uint16_t len)
   {
     if (sobuf || !buf || !len)
       return FAIL;
@@ -152,57 +208,114 @@ implementation {
     }
   }
 
-  async command error_t enableReceiveInterrupt()
+  async command error_t UartStream.enableReceiveInterrupt()
   {
-    if (!robuf)
-      call Registers.clrIfgRx();
-    call Registers.setIeRx();
-    rxie = FALSE;
-    return SUCCESS;
+    atomic {
+      if (!robuf)
+       call Registers.clrIfgRx();
+      call Registers.setIeRx();
+      rxie = FALSE;
+      return SUCCESS;
+    }
   }
 
-  async command error_t disableReceiveInterrupt()
+  async command error_t UartStream.disableReceiveInterrupt()
   {
-    if (!robuf) {
-      call Registers.clrIeRx();
-      call Registers.clrIfgRx();
-    } else
-      rxie = TRUE;
-    return SUCCESS;
+    atomic {
+      if (!robuf) {
+       call Registers.clrIeRx();
+       call Registers.clrIfgRx();
+      } else
+       rxie = TRUE;
+      return SUCCESS;
+    }
   }
 
-  async command error_t receive(uint8_t* buf, uint16_t len)
+  async command error_t UartByte.receive(uint8_t* byte, uint8_t timeout)
   {
-    if (robuf || !buf || !len)
+    atomic {
+      uint16_t t;
+
+      /* FIXME: race with UartStream.receive() */
+      if (robuf || !byte)
+       return FAIL;
+      /* TODO: implement timeout, byte-time units.  For now, 1-2 sec */
+      t = TBR;
+      while (t < TBR) {
+       if (call Registers.getIfgRx()) {
+         *byte = call Registers.getRxbuf();
+         return SUCCESS;
+       }
+      }
       return FAIL;
-    robuf = rbuf = buf;
-    rolen = rlen = len;
-    if (!call Registers.getIeRx) {
-      call Registers.clrIfgRx();
-      call Registers.setIeRx();
-      rxie = TRUE;
-    } else
-      rxie = FALSE;
+    }
+  }
+
+  async command error_t UartStream.receive(uint8_t* buf, uint16_t len)
+  {
+    atomic {
+      if (robuf || !buf || !len)
+       return FAIL;
+      robuf = rbuf = buf;
+      rolen = rlen = len;
+      if (!call Registers.getIeRx()) {
+       call Registers.clrIfgRx();
+       call Registers.setIeRx();
+       rxie = TRUE;
+      } else
+       rxie = FALSE;
+    }
   }
 
   async event void Interrupts.rx(uint8_t byte)
   {
-    if (robuf) {
-      /* receive() takes precedence if active */
-      while (rlen && call Registers.getIfgRx()) {
-       *rbuf = byte;
-       if (--rlen)
-         rbuf++;
-      }
-      if (rlen == 0 && robuf) {
-       if (rxie) {
-         call Registers.clrIeRx();
-         call Registers.clrIfgRx();
+    atomic {
+      if (robuf) {
+       /* receive() takes precedence if active */
+       while (rlen && call Registers.getIfgRx()) {
+         *rbuf = byte;
+         if (--rlen)
+           rbuf++;
        }
-       robuf = 0;
-       signal UartStream.receiveDone(robuf, rolen, SUCCESS);
-      }
-    } else
-      signal UartStream.receivedByte(byte);
+       if (rlen == 0 && robuf) {
+         if (rxie) {
+           call Registers.clrIeRx();
+           call Registers.clrIfgRx();
+         }
+         robuf = 0;
+         signal UartStream.receiveDone(robuf, rolen, SUCCESS);
+       }
+      } else
+       signal UartStream.receivedByte(byte);
+    }
   }
+
+  default async command const msp430_usci_uart_t* Configure.get()
+  {
+    const static msp430_usci_uart_t def = { 
+      ctl0: UCMODE_0,          /* async, lsb first, 8N1 */
+      ctl1: UCSWRST|UCSSEL_3,  /* clock uart from SMCLK */
+      brx: UBRX_1MHZ_115200,
+      mctl: UMCTL_1MHZ_115200,
+      irtctl: 0,
+      irrctl: 0,
+      abctl: 0,
+      ren: USCI_REN_NONE
+    };
+
+    return &def;
+  }
+
+  async event void Interrupts.i2cStart() {}
+  async event void Interrupts.i2cStop() {}
+  async event void Interrupts.i2cCal() {}
+  async event void Interrupts.brk() {}
+  async event void Interrupts.i2cNak() {}
+  async event void Counter.overflow() {}
+
+  default async event void UartStream.sendDone( uint8_t* buf, uint16_t len,
+      error_t error ) {}
+  default async event void UartStream.receivedByte( uint8_t byte ) {}
+  default async event void UartStream.receiveDone( uint8_t* buf, uint16_t len,
+      error_t error ) {}
 }