From 10acc57d16a648d746eed9d5c6264850f7c52fde Mon Sep 17 00:00:00 2001 From: smckown Date: Sun, 7 Sep 2008 18:09:37 +0000 Subject: [PATCH] Add some SPI implementation. --- tos/chips/msp430/usci/HplMsp430UsciC.nc | 2 + tos/chips/msp430/usci/Msp430SpiB1C.nc | 75 +++++++++++ tos/chips/msp430/usci/Msp430SpiP.nc | 166 ++++++++++++++++++++++++ tos/chips/msp430/usci/Msp430UartA0C.nc | 4 + tos/chips/msp430/usci/Msp430UartP.nc | 2 +- 5 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 tos/chips/msp430/usci/Msp430SpiB1C.nc create mode 100644 tos/chips/msp430/usci/Msp430SpiP.nc diff --git a/tos/chips/msp430/usci/HplMsp430UsciC.nc b/tos/chips/msp430/usci/HplMsp430UsciC.nc index 0b358eb8..c6ac8b24 100644 --- a/tos/chips/msp430/usci/HplMsp430UsciC.nc +++ b/tos/chips/msp430/usci/HplMsp430UsciC.nc @@ -80,7 +80,9 @@ implementation { UCB0CTL0_, UCB0CTL1_, UCB0RXBUF_, IFG2_) as Int0P; IntA0 = Int0P.IntA; IntB0 = Int0P.IntB; + #elif defined(__MSP430_HAS_USCIAB0__) + components new HplMsp430UsciRegP(UCA0CTL0_, UCA0CTL1_, UCA0BR0_, UCA0BR1_, UCA0MCTL_, 0/*UCA0I2CIE_*/, UCA0STAT_, UCA0RXBUF_, UCA0TXBUF_, UCA0ABCTL_, UCA0IRTCTL_, UCA0IRRCTL_, 0/*UCA0I2COA_*/, 0/*UCA0I2CSA_*/, IE2_, IFG2_, diff --git a/tos/chips/msp430/usci/Msp430SpiB1C.nc b/tos/chips/msp430/usci/Msp430SpiB1C.nc new file mode 100644 index 00000000..980f637f --- /dev/null +++ b/tos/chips/msp430/usci/Msp430SpiB1C.nc @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2008, Titanium Mirror, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the Technische Universität Berlin nor the names + * of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * This configuration provides the interface for using USCI_B1 in its SPI + * mode. + * + * @author R. Steve McKown + */ + +#if !defined(__MSP430_HAS_USCI_AB1__) +#error "Target does not have a USCI_B1 peripheral (SPI)" +#endif + +configuration Msp430SpiB1C { + provides { + interface Resource; + interface ResourceRequested; + interface SpiByte; + interface SpiPacket; + interface ArbiterInfo; /* ??? */ + } + uses interface Msp430UsciSpiConfigure; /* would be nice to use Msp430SpiConfigure, same as USART analog */ +} +implementation { + enum { + CLIENT_ID = unique(MSP430_USCIB1_RESOURCE) + }; + + components Msp430SpiP as SpiP; + SpiByte = SpiP; + SpiPacket = SpiP; + Msp430UsciSpiConfigure = SpiP; + + components new Msp430UsciA0C() as UsciC; + Resource = UsciC.Resource[CLIENT_ID]; + ResourceRequested = UsciC.ResourceRequested[CLIENT_ID]; + ArbiterInfo = UsciC.ArbiterInfo; + SpiP -> UsciC.Registers; + SpiP -> UsciC.Interrupts[CLIENT_ID]; + SpiP -> UsciC.ArbiterInfo; + UsciC.ResourceConfigure[CLIENT_ID] -> SpiP; + + components HplMsp430GeneralIOC as IOC; + SpiP.STE -> IOC.UCB1STE; + SpiP.SIMO -> IOC.UCB1SIMO; + SpiP.SOMI -> IOC.UCB1SOMI; + SpiP.SCL -> IOC.UCB1SCL; +} diff --git a/tos/chips/msp430/usci/Msp430SpiP.nc b/tos/chips/msp430/usci/Msp430SpiP.nc new file mode 100644 index 00000000..22584fd8 --- /dev/null +++ b/tos/chips/msp430/usci/Msp430SpiP.nc @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2008, Titanium Mirror, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of the Technische Universität Berlin nor the names + * of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Spi implementation using a USCI device. + * + * @author R. Steve McKown + */ + +generic module Msp430SpiP() { + provides { + interface SpiByte; + interface SpiPacket; + interface ResourceConfigure; + } + uses { + interface HplMsp430UsciReg as Registers; + interface HplMsp430UsciInt as Interrupts; + interface HplMsp430GeneralIO as STE; + interface HplMsp430GeneralIO as SIMO; + interface HplMsp430GeneralIO as SOMI; + interface HplMsp430GeneralIO as SCL; + interface Msp430UsciSpiConfigure; /* maybe just Msp430UsciConfigure */ + interface Counter + interface ArbiterInfo; + } +} +implementation { + #define saveBits(pin, pos, dir, out, ren) { \ + if (call pin.isOutput()) \ + dir |= (1 << pos); \ + if (call pin.getOut()) \ + out |= (1 << pos); \ + if (call pin.isRen()) \ + ren |= (1 << pos); \ + } + + #define restoreBits(pin, pos, dir, out, ren) { \ + if (ren & (1 << pos)) \ + call pin.enableRen(); \ + else \ + call pin.disableRen(); \ + if (out & (1 << pos)) \ + call pin.set(); \ + else \ + call pin.clr(); \ + if (dir & (1 << pos)) \ + call pin.makeOutput(); \ + else \ + call pin.makeInput(); \ + } + + uint8_t dir; /* Pin state storage to allow for proper unconfiguration */ + uint8_t out; + uint8_t ren; + + async command void ResourceConfigure.configure(); + { + call Registers.setCtl0(UCSYNC); + /* Save pin states */ + dir = out = ren = 0; + saveBits(STE, 0, dir, out, ren); + saveBits(SIMO, 1, dir, out, ren); + saveBits(SOMI, 2, dir, out, ren); + saveBits(SCL, 3, dir, out, ren); + /* FIXME: use Msp430UsciConfig to configure ports */ + /* FIXME: we may need to have REN/DIR stuff in the configuration... */ + if (call Registers.getCtl1(UCMODE_3) != UCMODE_0) { + call STE.selectModuleFunc(); + call SIMO.selectModuleFunc(); + call SOMI.selectModuleFunc(); + call SCL.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); + } + + 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(SIMO, 1, dir, out, ren); + restoreBits(SOMI, 2, dir, out, ren); + restoreBits(SCL, 3, dir, out, ren); + call SIMO.selectIOFunc(); + call SOMI.selectIOFunc(); + call SCL.selectIOFunc(); + /* Restore more if we were using 4-pin SPI */ + if (call Registers.getCtl1(UCMODE_3) != UCMODE_0) { + restoreBits(STE, 0, dir, out, ren); + call STE.selectIOFunc(); + } + } + + + async event void Interrupts.tx() + { + while (slen && call Registers.getIfgTx()) { + call Registers.setTxbuf(*sbuf); + if (--slen) + sbuf++; + } + if (slen == 0 && sobuf) { + call Registers.clrIeTx(); + call Registers.clrIfgTx(); + sobuf = 0; + signal UartStream.sendDone(sobuf, solen, SUCCESS); + } + } + + 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(); + } + robuf = 0; + signal UartStream.receiveDone(robuf, rolen, SUCCESS); + } + } else + signal UartStream.receivedByte(byte); + } +} diff --git a/tos/chips/msp430/usci/Msp430UartA0C.nc b/tos/chips/msp430/usci/Msp430UartA0C.nc index 4c07faa6..6bb97095 100644 --- a/tos/chips/msp430/usci/Msp430UartA0C.nc +++ b/tos/chips/msp430/usci/Msp430UartA0C.nc @@ -66,4 +66,8 @@ implementation { UartP -> UsciC.Interrupts[CLIENT_ID]; UartP -> UsciC.ArbiterInfo; UsciC.ResourceConfigure[CLIENT_ID] -> UartP; + + components HplMsp430GeneralIOC as IOC; + UartP.RXD -> IOC.UCA0RXD; + UartP.TXD -> IOC.UCA0TXD; } diff --git a/tos/chips/msp430/usci/Msp430UartP.nc b/tos/chips/msp430/usci/Msp430UartP.nc index b9f25ede..f00e704f 100644 --- a/tos/chips/msp430/usci/Msp430UartP.nc +++ b/tos/chips/msp430/usci/Msp430UartP.nc @@ -42,7 +42,7 @@ 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 -- 2.39.2