--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Generic async configuration interface.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+interface AsyncConfigure<val_t> {
+ async command val_t get();
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Provides HPL access to both registers and interrupts of all USCI devices on
+ * a supported msp430 processor. The interfaces available are created
+ * depending upon the type of msp430 for which the code is being compiled.
+ * Currently most parts with one or two USCI peripherals supported by mspgcc
+ * (msp430-gcc) should be supported. The most common will probably be the
+ * parts offering two USCI peripherals, which use names like these to describe
+ * their provided serial devices:
+ *
+ * USCI_A0 and USCI_B0, from the first USCI peripheral; and
+ * USCI_A1 and USCI_B1, from the second USCI peripheral.
+ *
+ * 'A' devices offer UART, LIN, IrDA and SPI modes of operation. 'B' devices
+ * are limited to SPI and I2C modes.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration HplMsp430UsciC {
+ provides {
+#if defined(__MSP430_HAS_USCI_AB0__) || defined(__MSP430_HAS_USCI__)
+ interface HplMsp430UsciReg as RegA0;
+ interface HplMsp430UsciInt as IntA0;
+ interface HplMsp430UsciReg as RegB0;
+ interface HplMsp430UsciInt as IntB0;
+#endif
+#if defined(__MSP430_HAS_USCI_AB1__)
+ interface HplMsp430UsciReg as RegA1;
+ interface HplMsp430UsciInt as IntA1;
+ interface HplMsp430UsciReg as RegB1;
+ interface HplMsp430UsciInt as IntB1;
+#endif
+ }
+}
+implementation {
+#if defined(__MSP430_HAS_USCI_AB0__) || defined(__MSP430_HAS_USCI__)
+ components new HplMsp430UsciRegP(UCA0CTL0_, UCA0CTL1_, UCA0BR0_, UCA0BR1_,
+ UCA0MCTL_, 0/*UCA0I2CIE_*/, UCA0STAT_, UCA0RXBUF_, UCA0TXBUF_, UCA0ABCTL_,
+ UCA0IRTCTL_, UCA0IRRCTL_, 0/*UCA0I2COA_*/, 0/*UCA0I2CSA_*/, IE2_, IFG2_,
+ UCA0RXIFG, UCA0TXIFG) as RegA0P;
+ RegA0 = RegA0P.Registers;
+
+ components new HplMsp430UsciRegP(UCB0CTL0_, UCB0CTL1_, UCB0BR0_, UCB0BR1_,
+ 0/*UCB0MCTL_*/, UCB0I2CIE_, UCB0STAT_, UCB0RXBUF_, UCB0TXBUF_,
+ 0/*UCB0ABCTL_*/, 0/*UCB0IRTCTL_*/, 0/*UCB0IRRCTL_*/, UCB0I2COA_,
+ UCB0I2CSA_, IE2_, IFG2_, UCB0RXIFG, UCB0TXIFG) as RegB0P;
+ RegB0 = RegB0P.Registers;
+
+ components HplMsp430UsciInt0P as Int0P;
+ IntA0 = Int0P.IntA;
+ IntB0 = Int0P.IntB;
+#endif
+
+#if defined(__MSP430_HAS_USCI_AB1__)
+ components new HplMsp430UsciRegP(UCA1CTL0_, UCA1CTL1_, UCA1BR0_, UCA1BR1_,
+ UCA1MCTL_, 0/*UCA1I2CIE_*/, UCA1STAT_, UCA1RXBUF_, UCA1TXBUF_, UCA1ABCTL_,
+ UCA1IRTCTL_, UCA1IRRCTL_, 0/*UCA1I2COA_*/, 0/*UCA1I2CSA_*/, UC1IE_,
+ UC1IFG_, UCA1RXIFG, UCA1TXIFG) as RegA1P;
+ RegA1 = RegA1P.Registers;
+
+ components new HplMsp430UsciRegP(UCB1CTL0_, UCB1CTL1_, UCB1BR0_, UCB1BR1_,
+ 0/*UCB1MCTL_*/, UCB1I2CIE_, UCB1STAT_, UCB1RXBUF_, UCB1TXBUF_,
+ 0/*UCB1ABCTL_*/, 0/*UCB1IRTCTL_*/, 0/*UCB1IRRCTL_*/, UCB1I2COA_,
+ UCB1I2CSA_, UC1IE_, UC1IFG_, UCB1RXIFG, UCB1TXIFG) as RegB1P;
+ RegB1 = RegB1P.Registers;
+
+ components HplMsp430UsciInt1P as Int1P;
+ IntA1 = Int1P.IntA;
+ IntB1 = Int1P.IntB;
+#endif
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Interrupt interface for USCI peripherals. Although A and B devices have
+ * different interrupt sets since B only support I2C, we use a single set for
+ * both so that upper layers need not deal with the different sets. This is
+ * critical in the case of SPI communications, which is supported by both A
+ * and B devices.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "Msp430Usci.h"
+
+interface HplMsp430UsciInt {
+ /**
+ * Signals a break received in UART modes if UCBRKIE is enabled. The
+ * provider must reset the UCxIFG.UCxxRXIFG and UCxSTAT.UCBRK bits prior to
+ * signalling the event to the user.
+ */
+ async event void brk();
+
+ /**
+ * Signals a character received for any USCI mode. The provider must reset
+ * UCxIFG.UCxxRXIFG before signalling the event to the user.
+ *
+ * @params byte The character received.
+ */
+ async event void rx(uint8_t byte);
+
+ /**
+ * Signals that the device's transmit buffer is empty and can accept
+ * another character. Note that the USCI device may still be in the
+ * process of transmitting the last character when this event is signalled.
+ * The UCxxTXIFG bit will automatically reset when the interface user writes
+ * a value to the related UCxxTXBUF register after receipt of this event.
+ */
+ async event void tx();
+
+ /**
+ * I2C mode only. Indicates the device has lost arbitration. Valid only in
+ * multi-master contexts.
+ */
+ async event void i2cCal();
+
+ /**
+ * I2C mode only. Indicates the device was expecting an ACK and it was not
+ * received.
+ */
+ async event void i2cNak();
+
+ /**
+ * I2C mode only. Indicates the device has detected a start condition
+ * together with its own address while in slave mode.
+ */
+ async event void i2cStart();
+
+ /**
+ * I2C mode only. Indicates the device has detected a stop condition while
+ * in slave mode.
+ */
+ async event void i2cStop();
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * HPL interrupt interface for the USCI0 peripheral.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "Msp430Usci.h"
+#include "msp430hardware.h"
+
+#if defined(USCIRX_VECTOR) /* odd def for MSP430G461 */
+#define USCIAB0RX_VECTOR USCIRX_VECTOR
+#endif
+#if defined(USCITX_VECTOR) /* odd def for MSP430G461 */
+#define USCIAB0TX_VECTOR USCITX_VECTOR
+#endif
+
+module HplMsp430UsciInt0P @safe() {
+ provides {
+ interface HplMsp430UsciInt as IntA;
+ interface HplMsp430UsciInt as IntB;
+ }
+}
+
+implementation
+{
+#if 0
+ MSP430REG_NORACE(UC0IFG);
+ MSP430REG_NORACE(UCA0CTL0);
+ MSP430REG_NORACE(UCA0CTL1);
+ MSP430REG_NORACE(UCA0RXBUF);
+ MSP430REG_NORACE(UCB0CTL0);
+ MSP430REG_NORACE(UCB0CTL1);
+ MSP430REG_NORACE(UCB0RXBUF);
+#endif
+
+ /* 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 & UC0IE, UCA0RXIE)) {
+ volatile uint8_t c = UCA0RXBUF; /* read to clear UCA0RXIFG */
+ if (READ_FLAG(UCA0CTL1, UCBRK)) {
+ CLR_FLAG(UCA0CTL1, UCBRK);
+ if (READ_FLAG(UCA0CTL0, UCMODE_3) == UCMODE_3)
+ CLR_FLAG(UCA0CTL1, UCDORM);
+ signal IntA.brk();
+ } else
+ signal IntA.rx(c);
+ } 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)) {
+ CLR_FLAG(UCB0STAT, UCNACKIFG);
+ CLR_FLAG(UC0IFG, UCB0TXIFG); /* Errata USCI25; 'reset' means clear? */
+ signal IntB.i2cNak();
+ } else if (READ_FLAG(UCB0STAT, UCSTTIFG)) {
+ CLR_FLAG(UCB0STAT, UCSTTIFG);
+ signal IntB.i2cStart();
+ } else if (READ_FLAG(UCB0STAT, UCSTPIFG)) {
+ CLR_FLAG(UCB0STAT, UCSTPIFG);
+ signal IntB.i2cStop();
+ }
+ }
+
+ /* 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 & UC0IE, UCB0RXIE))
+ signal IntB.rx(UCB0RXBUF); /* I2C receive */
+ else if (READ_FLAG(UC0IFG & UC0IE, UCA0TXIFG))
+ signal IntA.tx();
+ else if (READ_FLAG(UC0IFG & UC0IE, UCB0TXIFG))
+ signal IntB.tx();
+ }
+
+ default async event void IntA.brk() {}
+ default async event void IntA.rx(uint8_t byte) {}
+ default async event void IntA.tx() {}
+ /* i2c is not available for A devices, so the below are never signalled */
+ default async event void IntA.i2cCal() {}
+ default async event void IntA.i2cNak() {}
+ 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() {}
+ default async event void IntB.i2cCal() {}
+ default async event void IntB.i2cNak() {}
+ default async event void IntB.i2cStart() {}
+ default async event void IntB.i2cStop() {}
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * HPL interrupt interface for the USCI1 peripheral.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "Msp430Usci.h"
+#include "msp430hardware.h"
+
+module HplMsp430UsciInt1P @safe() {
+ provides {
+ interface HplMsp430UsciInt as IntA;
+ interface HplMsp430UsciInt as IntB;
+ }
+}
+
+implementation
+{
+#if 0
+ MSP430REG_NORACE(UC1IFG);
+ MSP430REG_NORACE(UCA1CTL0);
+ MSP430REG_NORACE(UCA1CTL1);
+ MSP430REG_NORACE(UCA1RXBUF);
+ MSP430REG_NORACE(UCB1CTL0);
+ MSP430REG_NORACE(UCB1CTL1);
+ MSP430REG_NORACE(UCB1RXBUF);
+#endif
+
+ /* This interrupt vector signals receive events. USCI_A1 can receive events
+ * for UART and SPI modes, while USCI_B1 can receive events for I2C and SPI
+ * modes.
+ */
+ TOSH_SIGNAL(USCIAB1RX_VECTOR) {
+ if (READ_FLAG(UC1IFG & UC1IE, UCA1RXIE)) {
+ volatile uint8_t c = UCA1RXBUF; /* read to clear UCA1RXIFG */
+ if (READ_FLAG(UCA1CTL1, UCBRK)) {
+ CLR_FLAG(UCA1CTL1, UCBRK);
+ if (READ_FLAG(UCA1CTL0, UCMODE_3) == UCMODE_3)
+ CLR_FLAG(UCA1CTL1, UCDORM);
+ signal IntA.brk();
+ } else
+ signal IntA.rx(c);
+ } else if (READ_FLAG(UC1IFG & UC1IE, UCB1RXIE)) {
+ signal IntB.rx(UCB1RXBUF); /* read clears UCB1RXIFG */
+
+ /* 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)) {
+ CLR_FLAG(UCB1STAT, UCNACKIFG);
+ CLR_FLAG(UC1IFG, UCB1TXIFG); /* Errata USCI25; 'reset' means clear? */
+ signal IntB.i2cNak();
+ } else if (READ_FLAG(UCB1STAT, UCSTTIFG)) {
+ CLR_FLAG(UCB1STAT, UCSTTIFG);
+ signal IntB.i2cStart();
+ } else if (READ_FLAG(UCB1STAT, UCSTPIFG)) {
+ CLR_FLAG(UCB1STAT, UCSTPIFG);
+ signal IntB.i2cStop();
+ }
+ }
+
+ /* This interrupt vector signals transmit events. USCI_A1 can receive events
+ * for UART and SPI modes, while USCI_B1 can receive events for I2C and SPI
+ * modes.
+ */
+ TOSH_SIGNAL(USCIAB1TX_VECTOR) {
+ if (READ_FLAG(UC1IFG & UC1IE, UCB1RXIE))
+ signal IntB.rx(UCB1RXBUF); /* I2C receive */
+ else if (READ_FLAG(UC1IFG & UC1IE, UCA1TXIFG))
+ signal IntA.tx();
+ else if (READ_FLAG(UC1IFG & UC1IE, UCB1TXIFG))
+ signal IntB.tx();
+ }
+
+ default async event void IntA.brk() {}
+ default async event void IntA.rx(uint8_t byte) {}
+ default async event void IntA.tx() {}
+ /* i2c is not available for A devices, so the below are never signalled */
+ default async event void IntA.i2cCal() {}
+ default async event void IntA.i2cNak() {}
+ 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() {}
+ default async event void IntB.i2cCal() {}
+ default async event void IntB.i2cNak() {}
+ default async event void IntB.i2cStart() {}
+ default async event void IntB.i2cStop() {}
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * HPL interface to a USCI peripheral device in UART mode.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "Msp430Usci.h"
+
+interface HplMsp430UsciReg {
+ /**
+ * Return the current mode.
+ */
+ async command msp430_usci_mode_t getMode();
+
+ /**
+ * Prepare to set the mode. If the device supports the requested mode, its
+ * UCxxCTL1.UCSWRST bit is set and TRUE is returned. If the device does not
+ * support the requested mode, no operations are performed and FALSE is
+ * returned.
+ *
+ * @param msp430usci_mode_t The desired USCI mode.
+ * @return bool TRUE if the device supports the requested mode, else FALSE.
+ */
+ async command bool setMode(msp430_usci_mode_t mode);
+
+ /**
+ * Get pointer to the UCxxCTL0 register associated with the USCI device.
+ *
+ * @return The pointer to the device's UCxxCTL0 register.
+ */
+ async command volatile uint8_t* ptrCtl0();
+
+ /**
+ * Get bits from the UCxxCTL0 register associated with the USCI device.
+ *
+ * @parm mask The bits upon which the operation is to be performed must be
+ * set in <t>mask</t>.
+ * @return The value of the device's UCxxCTL0 register ANDed with
+ * <t>mask</t>.
+ */
+ async command uint8_t getCtl0(uint8_t mask);
+
+ /**
+ * Set bits in the UCxxCTL0 register associated with the USCI device.
+ * The operation is equivalent to: <t>UCxxCTL0 |= mask</t>.
+ *
+ * @parm mask The bits in set in <t>mask</t> to set in UCxxCTL0.
+ */
+ async command void setCtl0(uint8_t mask);
+
+ /**
+ * Clear bits in the UCxxCTL0 register associated with the USCI device.
+ * The operation is equivalent to: <t>UCxxCTL0 &= ~mask</t>.
+ *
+ * @parm mask The bits in set in <t>mask</t> to clear in UCxxCTL0.
+ */
+ async command void clrCtl0(uint8_t mask);
+
+ /**
+ * Assign the values of the bits in <t>value</t>, whose corresponding bits in
+ * <t>mask</t> are set, in the UCxxCTL0 register. The operation is
+ * equivalent to: <t>UCxxCTL0 = (UCxxCTL0 & ~mask) | (value & mask)</t>.
+ */
+ //async command void assignCtl0(uint8_t mask, uint8_t value);
+ async command void assignCtl0(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxCTL1 register. See the methods that manipulate
+ * UCxxCTL0 for more information.
+ */
+ async command volatile uint8_t* ptrCtl1();
+ async command uint8_t getCtl1(uint8_t mask);
+ async command void setCtl1(uint8_t mask);
+ async command void clrCtl1(uint8_t mask);
+ //async command void assignCtl1(uint8_t mask, uint8_t value);
+ async command void assignCtl1(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxBR0 register. See the methods that manipulate
+ * UCxxCTL0 for more information.
+ */
+ async command volatile uint8_t* ptrBr0();
+ async command uint8_t getBr0(uint8_t mask);
+ async command void setBr0(uint8_t mask);
+ async command void clrBr0(uint8_t mask);
+ //async command void assignBr0(uint8_t mask, uint8_t value);
+ async command void assignBr0(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxBR1 register. See the methods that manipulate
+ * UCxxCTL0 for more information.
+ */
+ async command volatile uint8_t* ptrBr1();
+ async command uint8_t getBr1(uint8_t mask);
+ async command void setBr1(uint8_t mask);
+ async command void clrBr1(uint8_t mask);
+ //async command void assignBr1(uint8_t mask, uint8_t value);
+ async command void assignBr1(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxMCTL register. See the methods that manipulate
+ * UCxxCTL0 for more information. These methods perform no operation on
+ * providers implementing a USCI_Bx device.
+ */
+ async command volatile uint8_t* ptrMctl();
+ async command uint8_t getMctl(uint8_t mask);
+ async command void setMctl(uint8_t mask);
+ async command void clrMctl(uint8_t mask);
+ //async command void assignMctl(uint8_t mask, uint8_t value);
+ async command void assignMctl(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxI2CIE register. See the methods that
+ * manipulate UCxxCTL0 for more information. These methods perform no
+ * operation on providers implementing a USCI_Ax device.
+ */
+ async command volatile uint8_t* ptrI2Cie();
+ async command uint8_t getI2Cie(uint8_t mask);
+ async command void setI2Cie(uint8_t mask);
+ async command void clrI2Cie(uint8_t mask);
+ //async command void assignI2Cie(uint8_t mask, uint8_t value);
+ async command void assignI2Cie(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxSTAT register. See the methods that manipulate
+ * UCxxCTL0 for more information.
+ */
+ async command volatile uint8_t* ptrStat();
+ async command uint8_t getStat(uint8_t mask);
+ async command void setStat(uint8_t mask);
+ async command void clrStat(uint8_t mask);
+ //async command void assignStat(uint8_t mask, uint8_t value);
+ async command void assignStat(uint8_t value);
+
+ /**
+ * Return pointer to the UCAxxRXBUF register used by the USCI device.
+ */
+ async command volatile uint8_t* ptrRxbuf();
+
+ /**
+ * Read the contents of the UCAxxRXBUF register. This register cannot be
+ * written.
+ */
+ async command uint8_t getRxbuf();
+
+ /**
+ * Return pointer to the UCAxxTXBUF register used by the USCI device.
+ */
+ async command volatile uint8_t* ptrTxbuf();
+
+ /**
+ * Read the contents of the UCAxxTXBUF register.
+ */
+ async command uint8_t getTxbuf();
+
+ /**
+ * Write a byte to the UCAxxTXBUF register.
+ */
+ async command void setTxbuf(uint8_t byte);
+
+ /**
+ * Manipulate bits in the UCxxABCTL register. See the methods that
+ * manipulate UCxxCTL0 for more information. These methods perform no
+ * operation on providers implementing a USCI_Bx device.
+ */
+ async command volatile uint8_t* ptrAbctl();
+ async command uint8_t getAbctl(uint8_t mask);
+ async command void setAbctl(uint8_t mask);
+ async command void clrAbctl(uint8_t mask);
+ //async command void assignAbctl(uint8_t mask, uint8_t value);
+ async command void assignAbctl(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxIRTCTL register. See the methods that
+ * manipulate UCxxCTL0 for more information. These methods perform no
+ * operation on providers implementing a USCI_Bx device.
+ */
+ async command volatile uint8_t* ptrIrtctl();
+ async command uint8_t getIrtctl(uint8_t mask);
+ async command void setIrtctl(uint8_t mask);
+ async command void clrIrtctl(uint8_t mask);
+ //async command void assignIrtctl(uint8_t mask, uint8_t value);
+ async command void assignIrtctl(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxIRRCTL register. See the methods that
+ * manipulate UCxxCTL0 for more information. These methods perform no
+ * operation on providers implementing a USCI_Bx device.
+ */
+ async command volatile uint8_t* ptrIrrctl();
+ async command uint8_t getIrrctl(uint8_t mask);
+ async command void setIrrctl(uint8_t mask);
+ async command void clrIrrctl(uint8_t mask);
+ //async command void assignIrrctl(uint8_t mask, uint8_t value);
+ async command void assignIrrctl(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxI2COA register. See the methods that
+ * manipulate UCxxCTL0 for more information. These methods perform no
+ * operation on providers implementing a USCI_Ax device.
+ */
+ async command volatile uint8_t* ptrI2Coa();
+ async command uint8_t getI2Coa(uint8_t mask);
+ async command void setI2Coa(uint8_t mask);
+ async command void clrI2Coa(uint8_t mask);
+ //async command void assignI2Coa(uint8_t mask, uint8_t value);
+ async command void assignI2Coa(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxI2COA register. See the methods that
+ * manipulate UCxxCTL0 for more information. These methods perform no
+ * operation on providers implementing a USCI_Ax device.
+ */
+ async command volatile uint8_t* ptrI2Csa();
+ async command uint8_t getI2Csa(uint8_t mask);
+ async command void setI2Csa(uint8_t mask);
+ async command void clrI2Csa(uint8_t mask);
+ //async command void assignI2Csa(uint8_t mask, uint8_t value);
+ async command void assignI2Csa(uint8_t value);
+
+ /**
+ * Manipulate bits in the UCxxIE register. See the methods that manipulate
+ * UCxxCTL0 for more information.
+ */
+ async command bool getIeRx();
+ async command void setIeRx();
+ async command void clrIeRx();
+ async command bool getIeTx();
+ async command void setIeTx();
+ async command void clrIeTx();
+
+ /**
+ * Manipulate bits in the UCxxIFG register. See the methods that manipulate
+ * UCxxCTL0 for more information.
+ */
+ async command bool getIfgRx();
+ async command void clrIfgRx();
+ async command bool getIfgTx();
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * HPL register interface to USCI peripherals. The interface abstracts the
+ * differences between pysical devices (aka addresses) such that a user of
+ * the interface can equally use any USCI device, providing the device
+ * provides the necessary capabilities. For example, I2C is only available
+ * on USCI_Bx ports.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include "Msp430Usci.h"
+#include "msp430hardware.h"
+
+generic module HplMsp430UsciRegP(
+ uint16_t Ctl0_addr,
+ uint16_t Ctl1_addr,
+ uint16_t Br0_addr,
+ uint16_t Br1_addr,
+ uint16_t Mctl_addr, /* A devices only */
+ uint16_t I2Cie_addr, /* B devices only */
+ uint16_t Stat_addr,
+ uint16_t Rxbuf_addr,
+ uint16_t Txbuf_addr,
+ uint16_t Abctl_addr, /* A devices only */
+ uint16_t Irtctl_addr, /* A devices only */
+ uint16_t Irrctl_addr, /* A devices only */
+ uint16_t I2Coa_addr, /* B devices only */
+ uint16_t I2Csa_addr, /* B devices only */
+ uint16_t Ie_addr,
+ uint16_t Ifg_addr,
+ uint16_t UCxxRXIFG, /* We rely on xIE and xIFG at same bit positions */
+ uint16_t UCxxTXIFG
+ ) @safe() {
+ provides interface HplMsp430UsciReg as Registers;
+}
+
+implementation
+{
+ #define IS_USCI_Ax (Mctl_addr != 0)
+ #define IS_USCI_Bx (I2Cie_addr != 0)
+
+ #define UCxxCtl0 (*TCAST(volatile uint8_t* ONE, Ctl0_addr))
+ #define UCxxCtl1 (*TCAST(volatile uint8_t* ONE, Ctl1_addr))
+ #define UCxxBr0 (*TCAST(volatile uint8_t* ONE, Br0_addr))
+ #define UCxxBr1 (*TCAST(volatile uint8_t* ONE, Br1_addr))
+ #define UCAxMctl (*TCAST(volatile uint8_t* ONE, Mctl_addr))
+ #define UCBxI2Cie (*TCAST(volatile uint8_t* ONE, I2Cie_addr))
+ #define UCxxStat (*TCAST(volatile uint8_t* ONE, Stat_addr))
+ #define UCxxRxbuf (*TCAST(volatile uint8_t* ONE, Rxbuf_addr))
+ #define UCxxTxbuf (*TCAST(volatile uint8_t* ONE, Txbuf_addr))
+ #define UCAxAbctl (*TCAST(volatile uint8_t* ONE, Abctl_addr))
+ #define UCAxIrtctl (*TCAST(volatile uint8_t* ONE, Irtctl_addr))
+ #define UCAxIrrctl (*TCAST(volatile uint8_t* ONE, Irrctl_addr))
+ #define UCBxI2Coa (*TCAST(volatile uint8_t* ONE, I2Coa_addr))
+ #define UCBxI2Csa (*TCAST(volatile uint8_t* ONE, I2Csa_addr))
+ #define UCxxIe (*TCAST(volatile uint8_t* ONE, Ie_addr))
+ #define UCxxIfg (*TCAST(volatile uint8_t* ONE, Ifg_addr))
+
+#if 0
+ #define ASSIGNBITS(reg, mask, value) \
+ (reg = ((reg) & ~(mask)) | ((value) & (mask)))
+#endif
+
+ #define RENDER(name) \
+ async command volatile uint8_t* Registers.ptr##name() { \
+ return &UCxx##name; \
+ } \
+ async command uint8_t Registers.get##name(uint8_t mask) { \
+ return READ_FLAG(UCxx##name, mask); \
+ } \
+ async command void Registers.set##name(uint8_t mask) { \
+ SET_FLAG(UCxx##name, mask); \
+ } \
+ async command void Registers.clr##name(uint8_t mask) { \
+ CLR_FLAG(UCxx##name, mask); \
+ } \
+ async command void Registers.assign##name(uint8_t value) { \
+ UCxx##name = value; \
+ }
+
+ #define RENDER_A(name) \
+ async command volatile uint8_t* Registers.ptr##name() { \
+ return &UCAx##name; \
+ } \
+ async command uint8_t Registers.get##name(uint8_t mask) { \
+ if (IS_USCI_Ax) \
+ return READ_FLAG(UCAx##name, mask); \
+ else \
+ return 0; \
+ } \
+ async command void Registers.set##name(uint8_t mask) { \
+ if (IS_USCI_Ax) \
+ SET_FLAG(UCAx##name, mask); \
+ } \
+ async command void Registers.clr##name(uint8_t mask) { \
+ if (IS_USCI_Ax) \
+ CLR_FLAG(UCAx##name, mask); \
+ } \
+ async command void Registers.assign##name(uint8_t value) { \
+ if (IS_USCI_Ax) \
+ UCAx##name = value; \
+ }
+
+ #define RENDER_B(name) \
+ async command volatile uint8_t* Registers.ptr##name() { \
+ return &UCBx##name; \
+ } \
+ async command uint8_t Registers.get##name(uint8_t mask) { \
+ if (IS_USCI_Bx) \
+ return READ_FLAG(UCBx##name, mask); \
+ else \
+ return 0; \
+ } \
+ async command void Registers.set##name(uint8_t mask) { \
+ if (IS_USCI_Bx) \
+ SET_FLAG(UCBx##name, mask); \
+ } \
+ async command void Registers.clr##name(uint8_t mask) { \
+ if (IS_USCI_Bx) \
+ CLR_FLAG(UCBx##name, mask); \
+ } \
+ async command void Registers.assign##name(uint8_t value) { \
+ if (IS_USCI_Bx) \
+ UCBx##name = value; \
+ }
+
+#if 0
+ MSP430REG_NORACE(UCxxCtl0);
+ MSP430REG_NORACE(UCxxCtl0);
+ MSP430REG_NORACE(UCxxCtl1);
+ MSP430REG_NORACE(UCxxBr0);
+ MSP430REG_NORACE(UCxxBr1);
+ MSP430REG_NORACE(UCAxMctl);
+ MSP430REG_NORACE(UCBxI2Cie);
+ MSP430REG_NORACE(UCxxStat);
+ MSP430REG_NORACE(UCxxRxbuf);
+ MSP430REG_NORACE(UCxxTxbuf);
+ MSP430REG_NORACE(UCAxAbctl);
+ MSP430REG_NORACE(UCAxIrtctl);
+ MSP430REG_NORACE(UCAxIrrctl);
+ MSP430REG_NORACE(UCBxI2Coa);
+ MSP430REG_NORACE(UCBxI2Csa);
+ MSP430REG_NORACE(UCxIe);
+ MSP430REG_NORACE(UCxIfg);
+#endif
+
+ async command msp430_usci_mode_t Registers.getMode()
+ {
+ if (READ_FLAG(UCxxCtl0, UCSYNC)) {
+ if (READ_FLAG(UCxxCtl0, UCMODE_3) == UCMODE_3)
+ return USCI_I2C;
+ else
+ return USCI_SPI;
+ } else {
+ return USCI_UART;
+ }
+ }
+
+ /* Doesn't really set the mode, but checks the most for the device and inits
+ * the device.
+ */
+ async command bool Registers.setMode(msp430_usci_mode_t mode)
+ {
+ if (mode == USCI_UART && IS_USCI_Bx)
+ return FALSE;
+ if (mode == USCI_I2C && IS_USCI_Ax)
+ return FALSE;
+ SET_FLAG(UCxxCtl1, UCSWRST);
+ return TRUE;
+ }
+
+ RENDER(Ctl0);
+ RENDER(Ctl1);
+ RENDER(Br0);
+ RENDER(Br1);
+ RENDER_A(Mctl);
+ RENDER_B(I2Cie);
+ RENDER(Stat);
+
+ /* RENDER(Rxbuf); */
+ async command volatile uint8_t* Registers.ptrRxbuf()
+ {
+ return &UCxxRxbuf;
+ }
+
+ async command uint8_t Registers.getRxbuf()
+ {
+ return UCxxRxbuf;
+ }
+
+ /* RENDER(Txbuf); */
+ async command volatile uint8_t* Registers.ptrTxbuf()
+ {
+ return &UCxxTxbuf;
+ }
+
+ async command uint8_t Registers.getTxbuf()
+ {
+ return UCxxTxbuf;
+ }
+
+ async command void Registers.setTxbuf(uint8_t byte)
+ {
+ UCxxTxbuf = byte;
+ }
+
+ RENDER_A(Abctl);
+ RENDER_A(Irtctl);
+ RENDER_A(Irrctl);
+ RENDER_B(I2Coa);
+ RENDER_B(I2Csa);
+
+ /* RENDER(Ie); */
+ async command bool Registers.getIeRx()
+ {
+ return READ_FLAG(UCxxIe, UCxxRXIFG);
+ }
+
+ async command void Registers.setIeRx()
+ {
+ SET_FLAG(UCxxIe, UCxxRXIFG);
+ }
+
+ async command void Registers.clrIeRx()
+ {
+ CLR_FLAG(UCxxIe, UCxxRXIFG);
+ }
+
+ async command bool Registers.getIeTx()
+ {
+ return READ_FLAG(UCxxIe, UCxxTXIFG);
+ }
+
+ async command void Registers.setIeTx()
+ {
+ SET_FLAG(UCxxIe, UCxxTXIFG);
+ }
+
+ async command void Registers.clrIeTx()
+ {
+ CLR_FLAG(UCxxIe, UCxxTXIFG);
+ }
+
+ /* RENDER(Ifg); */
+ async command bool Registers.getIfgRx()
+ {
+ return READ_FLAG(UCxxIfg, UCxxRXIFG);
+ }
+
+ async command void Registers.clrIfgRx()
+ {
+ CLR_FLAG(UCxxIfg, UCxxRXIFG);
+ }
+
+ async command bool Registers.getIfgTx()
+ {
+ return READ_FLAG(UCxxIfg, UCxxTXIFG);
+ }
+}
--- /dev/null
+/*
+ * 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_A0 in its SPI
+ * mode.
+ *
+ * The instantiator should set the blockSize, which represents the maximum
+ * number of bytes the underlying SPI stack will transmit or receive in a
+ * single interrupt service. Increasing the block size decreases SPI
+ * communications time at the expense of reducing system responsiveness to
+ * other events.
+ *
+ * The blockSize is best set by considering the maximum time the SPI stack
+ * should be able to delay other events. A rule of thumb formula would be:
+ *
+ * block_time = block_size / (spi_bitclock/8)
+ *
+ * For example, using a 500KHZ SPI bitclock, a block size of 64 bytes
+ * equates to a block time of 1 ms. Note that this calculation is rough
+ * because it does not take into account ISR overhead and other factors.
+ *
+ * The implementation will use a default blockSize if set to 0 here.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#if !defined(__MSP430_HAS_USCI_AB0__)
+#error "Target does not have a USCI_A0 peripheral (SPI)"
+#endif
+
+#include "Msp430Usci.h"
+
+generic configuration Msp430SpiA0C(uint16_t blockSize) {
+ provides {
+ interface Resource;
+ interface ResourceRequested;
+ interface SpiByte;
+ interface SpiPacket;
+ interface ArbiterInfo; /* ??? */
+ }
+ uses {
+ interface AsyncConfigure<const msp430_usci_spi_t*> as Configure;
+ interface GeneralIO as CSn; /* wire only if a SPI slave only */
+ }
+}
+implementation {
+ enum {
+ CLIENT_ID = unique(MSP430_USCIA0_RESOURCE)
+ };
+
+ components new Msp430SpiP(blockSize) as SpiP;
+ SpiByte = SpiP;
+ SpiPacket = SpiP;
+ Configure = SpiP;
+ CSn = SpiP;
+
+ components 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.UCA0STE;
+ SpiP.SIMO -> IOC.UCA0SIMO;
+ SpiP.SOMI -> IOC.UCA0SOMI;
+ SpiP.CLK -> IOC.UCA0CLK;
+}
--- /dev/null
+/*
+ * 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_B0 in its SPI
+ * mode.
+ *
+ * The instantiator should set the blockSize, which represents the maximum
+ * number of bytes the underlying SPI stack will transmit or receive in a
+ * single interrupt service. Increasing the block size decreases SPI
+ * communications time at the expense of reducing system responsiveness to
+ * other events.
+ *
+ * The blockSize is best set by considering the maximum time the SPI stack
+ * should be able to delay other events. A rule of thumb formula would be:
+ *
+ * block_time = block_size / (spi_bitclock/8)
+ *
+ * For example, using a 500KHZ SPI bitclock, a block size of 64 bytes
+ * equates to a block time of 1 ms. Note that this calculation is rough
+ * because it does not take into account ISR overhead and other factors.
+ *
+ * The implementation will use a default blockSize if set to 0 here.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#if !defined(__MSP430_HAS_USCI_AB0__)
+#error "Target does not have a USCI_B0 peripheral (SPI)"
+#endif
+
+#include "Msp430Usci.h"
+
+generic configuration Msp430SpiB0C(uint16_t blockSize) {
+ provides {
+ interface Resource;
+ interface ResourceRequested;
+ interface SpiByte;
+ interface SpiPacket;
+ interface ArbiterInfo; /* ??? */
+ }
+ uses {
+ interface AsyncConfigure<const msp430_usci_spi_t*> as Configure;
+ interface GeneralIO as CSn; /* wire only if a SPI slave only */
+ }
+}
+implementation {
+ enum {
+ CLIENT_ID = unique(MSP430_USCIB0_RESOURCE)
+ };
+
+ components new Msp430SpiP(blockSize) as SpiP;
+ SpiByte = SpiP;
+ SpiPacket = SpiP;
+ Configure = SpiP;
+ CSn = SpiP;
+
+ components Msp430UsciB0C 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.UCB0STE;
+ SpiP.SIMO -> IOC.UCB0SIMO;
+ SpiP.SOMI -> IOC.UCB0SOMI;
+ SpiP.CLK -> IOC.UCB0CLK;
+}
--- /dev/null
+/*
+ * 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.
+ *
+ * The instantiator should set the blockSize, which represents the maximum
+ * number of bytes the underlying SPI stack will transmit or receive in a
+ * single interrupt service. Increasing the block size decreases SPI
+ * communications time at the expense of reducing system responsiveness to
+ * other events.
+ *
+ * The blockSize is best set by considering the maximum time the SPI stack
+ * should be able to delay other events. A rule of thumb formula would be:
+ *
+ * block_time = block_size / (spi_bitclock/8)
+ *
+ * For example, using a 500KHZ SPI bitclock, a block size of 64 bytes
+ * equates to a block time of 1 ms. Note that this calculation is rough
+ * because it does not take into account ISR overhead and other factors.
+ *
+ * The implementation will use a default blockSize if set to 0 here.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#if !defined(__MSP430_HAS_USCI_AB1__)
+#error "Target does not have a USCI_B1 peripheral (SPI)"
+#endif
+
+#include "Msp430Usci.h"
+
+generic configuration Msp430SpiB1C(uint16_t blockSize) {
+ provides {
+ interface Resource;
+ interface ResourceRequested;
+ interface SpiByte;
+ interface SpiPacket;
+ interface ArbiterInfo; /* ??? */
+ }
+ uses {
+ interface AsyncConfigure<const msp430_usci_spi_t*> as Configure;
+ interface GeneralIO as CSn; /* wire only if a SPI slave only */
+ }
+}
+implementation {
+ enum {
+ CLIENT_ID = unique(MSP430_USCIB1_RESOURCE)
+ };
+
+ components new Msp430SpiP(blockSize) as SpiP;
+ SpiByte = SpiP;
+ SpiPacket = SpiP;
+ Configure = SpiP;
+ CSn = SpiP;
+
+ components Msp430UsciB1C 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.CLK -> IOC.UCB1CLK;
+}
--- /dev/null
+/*
+ * 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. When being used as a SPI slave, the
+ * CSn interface should be wired to the chip select driven by the SPI master so
+ * the module can know when a communications session is terminated unexpectedly.
+ *
+ * TODO: Implement error checking via UCxxSTAT
+ *
+ * NOTE: Define NO_REN_ON_SPI to disable PxREN bits when SPI is acquired.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+generic module Msp430SpiP(uint16_t blockSize) {
+ provides {
+ interface SpiByte;
+ interface SpiPacket;
+ interface ResourceConfigure;
+ }
+ uses {
+ interface HplMsp430UsciReg as Registers;
+ interface HplMsp430UsciInt as Interrupts;
+ interface GeneralIO as CSn;
+ interface HplMsp430GeneralIO as STE;
+ interface HplMsp430GeneralIO as SIMO;
+ interface HplMsp430GeneralIO as SOMI;
+ interface HplMsp430GeneralIO as CLK;
+ interface AsyncConfigure<const msp430_usci_spi_t*> as Configure;
+ interface ArbiterInfo;
+ }
+}
+implementation {
+ enum {
+ BLOCKSIZE_DEFAULT = 64,
+
+ /* Bit positions in m_pins */
+ PINS_STE = 0,
+ PINS_SOMI,
+ PINS_SIMO,
+ PINS_CLK,
+#ifdef NO_REN_ON_SPI
+ PINS_RENADDR, /* This gets added to store the PxREN bit */
+#endif
+ };
+
+ uint8_t m_pins;
+ norace uint8_t* m_txBuf;
+ norace uint8_t* m_rxBuf;
+ norace uint16_t m_len;
+ norace uint16_t m_pos;
+
+ inline bool is4pin() /* TRUE if the SPI bus is in 4-pin mode */
+ {
+ return (call Registers.getCtl0(UCMODE_3)) != UCMODE_0;
+ }
+
+ inline bool isBusy() /* TRUE if a SPI transaction is in progress */
+ {
+ atomic return m_len != 0;
+ }
+
+ async command void ResourceConfigure.configure()
+ {
+ atomic {
+ const msp430_usci_spi_t* config = call Configure.get();
+ uint8_t ctl0;
+
+ call Registers.setCtl1(UCSWRST);
+
+ /* UCMODE_3 is invalid for SPI. Presume the configuration data
+ * are wrong and force 3-pin SPI as a minimially safe alternative.
+ */
+ ctl0 = config->ctl0 | UCSYNC;
+ if ((ctl0 & UCMODE_3) == UCMODE_3)
+ ctl0 &= ~(UCMODE_3);
+
+ /* Configure USCI registers */
+ call Registers.assignCtl0(ctl0);
+ call Registers.assignCtl1(config->ctl1 | UCSWRST);
+ call Registers.assignBr0(config->brx & 0xff);
+ call Registers.assignBr1(config->brx >> 8);
+ call Registers.assignMctl(0);
+ if (config->uclisten)
+ call Registers.setStat(UCLISTEN);
+ else
+ call Registers.clrStat(UCLISTEN);
+
+ /* Configure pins for SPI, saving prior pin states */
+ m_pins = 0;
+#ifdef NO_REN_ON_SPI
+ /* - First save off and disable PxREN bits */
+ if (is4pin() && call STE.isRen()) {
+ m_pins |= (1 << (PINS_STE + PINS_RENADDR));
+ call STE.disableRen();
+ }
+ if (call SOMI.isRen()) {
+ m_pins |= (1 << (PINS_SOMI + PINS_RENADDR));
+ call SOMI.disableRen();
+ }
+ if (call SIMO.isRen()) {
+ m_pins |= (1 << (PINS_SIMO + PINS_RENADDR));
+ call SIMO.disableRen();
+ }
+ if (call CLK.isRen()) {
+ m_pins |= (1 << (PINS_CLK + PINS_RENADDR));
+ call CLK.disableRen();
+ }
+#endif
+ /* - Then save off IOFunc state and enable ModuleFunc */
+ if (is4pin() && call STE.isIOFunc()) {
+ m_pins |= (1 << PINS_STE);
+ call STE.selectModuleFunc();
+ }
+ if (call SOMI.isIOFunc()) {
+ m_pins |= (1 << PINS_SOMI);
+ call SOMI.selectModuleFunc();
+ }
+ if (call SIMO.isIOFunc()) {
+ m_pins |= (1 << PINS_SIMO);
+ call SIMO.selectModuleFunc();
+ }
+ if (call CLK.isIOFunc()) {
+ m_pins |= (1 << PINS_CLK);
+ call CLK.selectModuleFunc();
+ }
+
+ /* Clear interrupts; we'll add them as needed */
+ call Registers.clrIeRx();
+ call Registers.clrIeTx();
+
+ /* Enable the device */
+ call Registers.clrCtl1(UCSWRST);
+ }
+ }
+
+ task void signalSendDone()
+ {
+ error_t error = (m_pos == m_len) ? SUCCESS : FAIL;
+
+ m_len = 0;
+ atomic signal SpiPacket.sendDone(m_txBuf, m_rxBuf, m_pos, error);
+ }
+
+ async command void ResourceConfigure.unconfigure()
+ {
+ atomic {
+ /* Disable the device */
+ call Registers.setCtl1(UCSWRST);
+
+ /* Ensure SpiPacket.sendDone is posted if a trx was in progress */
+ if (m_len)
+ post signalSendDone();
+
+ /* Clear interrupts and interrupt flags. We only used Rx */
+ call Registers.clrIeRx();
+ call Registers.clrIfgRx();
+
+ /* Restore pins to their pre-configure state */
+ /* - First restore IOFunc states */
+ if (is4pin() && (m_pins & (1 << PINS_STE)))
+ call STE.selectIOFunc();
+ if (m_pins & (1 << PINS_SIMO))
+ call SIMO.selectIOFunc();
+ if (m_pins & (1 << PINS_SOMI))
+ call SOMI.selectIOFunc();
+ if (m_pins & (1 << PINS_CLK))
+ call CLK.selectIOFunc();
+ /* - Then restore PxREN bits */
+#ifdef NO_REN_ON_SPI
+ if (is4pin() && (m_pins & (1 << (PINS_STE + PINS_RENADDR))))
+ call STE.enableRen();
+ if (m_pins & (1 << (PINS_SIMO + PINS_RENADDR)))
+ call SIMO.enableRen();
+ if (m_pins & (1 << (PINS_SOMI + PINS_RENADDR)))
+ call SOMI.enableRen();
+ if (m_pins & (1 << (PINS_CLK + PINS_RENADDR)))
+ call CLK.enableRen();
+#endif
+ }
+ }
+
+ bool waitOnRx()
+ {
+ for (;;) {
+ if (call Registers.getIfgRx())
+ return TRUE;
+ if (call CSn.get()) /* SPI master has unselected us */
+ return FALSE;
+ }
+ }
+
+ bool waitOnTx()
+ {
+ for (;;) {
+ if (call Registers.getIfgTx())
+ return TRUE;
+ if (call CSn.get()) /* SPI master has unselected us */
+ return FALSE;
+ }
+ }
+
+ async command uint8_t SpiByte.write(uint8_t byte)
+ {
+ atomic {
+ if (isBusy())
+ return 0;
+ else {
+ waitOnTx();
+ call Registers.setTxbuf(byte);
+ waitOnRx();
+ return call Registers.getRxbuf();
+ }
+ }
+ }
+
+ /* If we are a slave, return FALSE if the master has unasserted CSn. */
+ bool sendData()
+ {
+ atomic {
+ uint16_t end = m_pos + (blockSize ? blockSize : BLOCKSIZE_DEFAULT);
+ uint8_t tmp;
+
+ if (end > m_len)
+ end = m_len;
+ waitOnTx(); /* Don't assume that the last tx is done already */
+ call Registers.setTxbuf(m_txBuf ? m_txBuf[m_pos] : 0);
+ while (++m_pos < end) {
+ waitOnRx();
+ tmp = call Registers.getRxbuf();
+ if (m_rxBuf)
+ m_rxBuf[m_pos - 1] = tmp;
+ waitOnTx();
+ call Registers.setTxbuf(m_txBuf ? m_txBuf[m_pos] : 0);
+ }
+ return call CSn.get() ? FALSE : TRUE;
+ }
+ }
+
+ async command error_t SpiPacket.send(uint8_t* txBuf, uint8_t* rxBuf,
+ uint16_t len)
+ {
+ if (isBusy() || (!txBuf && !rxBuf) || len == 0)
+ return FAIL;
+ else {
+ m_txBuf = txBuf;
+ m_rxBuf = rxBuf;
+ m_len = len;
+ m_pos = 0;
+ if (sendData())
+ call Registers.setIeRx();
+ else
+ post signalSendDone();
+ return SUCCESS;
+ }
+ }
+
+ async event void Interrupts.tx() {}
+
+ async event void Interrupts.rx(uint8_t byte)
+ {
+ if (m_rxBuf)
+ m_rxBuf[m_pos - 1] = byte;
+
+ if (m_pos < m_len) {
+ if (sendData())
+ return;
+ }
+ call Registers.clrIeRx();
+ post signalSendDone();
+ }
+
+ default async event void SpiPacket.sendDone(uint8_t*, uint8_t*, uint16_t,
+ error_t) {}
+
+ default async command const msp430_usci_spi_t* Configure.get()
+ {
+ const static msp430_usci_spi_t def = {
+ ctl0: UCSYNC | UCMODE_0 | UCMST, /* 3-pin SPI mode 0, LSB first */
+ ctl1: UCSWRST | UCSSEL_3, /* SPI clock source is SMCLK */
+ brx: 10, /* SPI clock=SMCLK/10; ~105KHz if SMCLK=1MHz */
+ uclisten: FALSE,
+ 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() {}
+
+ default async command bool CSn.get() { return FALSE; }
+}
--- /dev/null
+/*
+ * 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_A0 in its UART
+ * mode.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#if !defined(__MSP430_HAS_USCI_AB0__)
+#error "Target does not have a USCI_A0 peripheral (UART)"
+#endif
+
+#include "Msp430Usci.h"
+
+generic configuration Msp430UartA0C() {
+ provides {
+ interface Resource;
+ interface ResourceRequested;
+ interface UartStream;
+ interface UartByte;
+ interface ArbiterInfo; /* ??? */
+ }
+ uses interface AsyncConfigure<const msp430_usci_uart_t*> as Configure;
+}
+implementation {
+ enum {
+ CLIENT_ID = unique(MSP430_USCIA0_RESOURCE)
+ };
+
+ components new Msp430UartP() as UartP;
+ UartStream = UartP;
+ UartByte = UartP;
+ Configure = UartP;
+
+ components Msp430UsciA0C as UsciC;
+ Resource = UsciC.Resource[CLIENT_ID];
+ ResourceRequested = UsciC.ResourceRequested[CLIENT_ID];
+ ArbiterInfo = UsciC.ArbiterInfo;
+ UartP -> UsciC.Registers;
+ 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;
+}
--- /dev/null
+/*
+ * 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_A1 in its UART
+ * mode.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#if !defined(__MSP430_HAS_USCI_AB0__)
+#error "Target does not have a USCI_A1 peripheral (UART)"
+#endif
+
+#include "Msp430Usci.h"
+
+generic configuration Msp430UartA1C() {
+ provides {
+ interface Resource;
+ interface ResourceRequested;
+ interface UartStream;
+ interface UartByte;
+ interface ArbiterInfo; /* ??? */
+ }
+ uses interface AsyncConfigure<const msp430_usci_uart_t*> as Configure;
+}
+implementation {
+ enum {
+ CLIENT_ID = unique(MSP430_USCIA1_RESOURCE)
+ };
+
+ components new Msp430UartP() as UartP;
+ UartStream = UartP;
+ UartByte = UartP;
+ Configure = UartP;
+
+ components Msp430UsciA1C as UsciC;
+ Resource = UsciC.Resource[CLIENT_ID];
+ ResourceRequested = UsciC.ResourceRequested[CLIENT_ID];
+ ArbiterInfo = UsciC.ArbiterInfo;
+ UartP -> UsciC.Registers;
+ UartP -> UsciC.Interrupts[CLIENT_ID];
+ UartP -> UsciC.ArbiterInfo;
+ UsciC.ResourceConfigure[CLIENT_ID] -> UartP;
+
+ components HplMsp430GeneralIOC as IOC;
+ UartP.RXD -> IOC.UCA1RXD;
+ UartP.TXD -> IOC.UCA1TXD;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Uart implementation using a USCI device.
+ *
+ * TODO: Implement blocking like in Msp430UartSpiP.nc.
+ * Implement error checking via UCAxSTAT.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+generic module Msp430UartP() {
+ provides {
+ interface UartStream;
+ interface UartByte;
+ interface ResourceConfigure;
+ }
+ uses {
+ interface HplMsp430UsciReg as Registers;
+ interface HplMsp430UsciInt as Interrupts;
+ interface HplMsp430GeneralIO as RXD;
+ interface HplMsp430GeneralIO as TXD;
+ interface AsyncConfigure<const msp430_usci_uart_t*> as Configure;
+ interface Counter<T32khz,uint16_t>;
+ interface ArbiterInfo;
+ }
+}
+implementation {
+ enum {
+ /* Bit positions in m_pins */
+ PINS_RXD = 1,
+ PINS_TXD
+ };
+
+ uint8_t m_pins;
+ uint8_t* m_sobuf; /* Original buffer ptr from UartStream.send() */
+ uint16_t m_solen; /* Original buffer len from UartStream.send() */
+ uint8_t* m_sbuf; /* Position of next char to send */
+ uint16_t m_slen; /* Len of chars in m_sbuf to send */
+ bool m_rxie; /* Set if rxie has been enabled to UartStream.receive() */
+ uint8_t* m_robuf; /* Original receive buffer */
+ uint16_t m_rolen; /* Original (maximum) receive len */
+ uint8_t* m_rbuf; /* Position of next byte in which to receive a char */
+ uint16_t m_rlen; /* Remaining length in receive buffer */
+
+ sfrb(MYBRX, 219U);
+
+ async command void ResourceConfigure.configure()
+ {
+ 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);
+ if (config->uclisten)
+ call Registers.setStat(UCLISTEN);
+ else
+ call Registers.clrStat(UCLISTEN);
+
+ /* Configure pins for UART, saving prior pin states */
+ m_pins = 0;
+ if (call RXD.isIOFunc()) {
+ m_pins |= (1 << PINS_RXD);
+ call RXD.selectModuleFunc();
+ }
+ if (call TXD.isIOFunc()) {
+ m_pins |= (1 << PINS_TXD);
+ call TXD.selectModuleFunc();
+ }
+
+ /* 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()
+ {
+ atomic {
+ /* Disable the device */
+ call Registers.setCtl1(UCSWRST);
+
+ /* Clear interrupts and interrupt flags */
+ call Registers.clrIeRx();
+ call Registers.clrIeTx();
+ call Registers.clrIfgRx();
+
+ /* Restore pins to their pre-configure state */
+ if (m_pins & PINS_RXD)
+ call RXD.selectIOFunc();
+ if (m_pins & PINS_TXD)
+ call TXD.selectIOFunc();
+ }
+ }
+
+ async command error_t UartByte.send(uint8_t byte)
+ {
+ atomic {
+ while (!call Registers.getIfgTx());
+ call Registers.setTxbuf(byte);
+ return SUCCESS;
+ }
+ }
+
+ async command error_t UartStream.send(uint8_t* buf, uint16_t len)
+ {
+ atomic {
+ if (m_sobuf || !buf || !len)
+ return FAIL;
+ m_sbuf = m_sobuf = buf;
+ m_slen = m_solen = len;
+ call Registers.setIeTx();
+ return SUCCESS;
+ }
+ }
+
+ async event void Interrupts.tx()
+ {
+ /* FIXME: this can cause an arbitrarily long ISR, if m_slen is large.
+ * But depending on timing, we may always only write 1 byte.
+ */
+ while (!call Registers.getIfgTx()); /* in case interleaved UB.send */
+ while (m_slen && call Registers.getIfgTx()) {
+ call Registers.setTxbuf(*m_sbuf);
+ if (--m_slen)
+ m_sbuf++;
+ }
+ if (m_slen == 0) {
+ call Registers.clrIeTx();
+ m_sobuf = 0;
+ signal UartStream.sendDone(m_sobuf, m_solen, SUCCESS);
+ }
+ }
+
+ async command error_t UartStream.enableReceiveInterrupt()
+ {
+ atomic {
+ if (!m_robuf)
+ call Registers.clrIfgRx();
+ call Registers.setIeRx();
+ m_rxie = FALSE;
+ return SUCCESS;
+ }
+ }
+
+ async command error_t UartStream.disableReceiveInterrupt()
+ {
+ atomic {
+ if (!m_robuf) {
+ call Registers.clrIeRx();
+ call Registers.clrIfgRx();
+ } else
+ m_rxie = TRUE;
+ return SUCCESS;
+ }
+ }
+
+ async command error_t UartByte.receive(uint8_t* byte, uint8_t timeout)
+ {
+ atomic {
+ uint16_t t;
+
+ /* FIXME: race with UartStream.receive() */
+ if (m_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;
+ }
+ }
+
+ async command error_t UartStream.receive(uint8_t* buf, uint16_t len)
+ {
+ atomic {
+ if (m_robuf || !buf || !len)
+ return FAIL;
+ m_robuf = m_rbuf = buf;
+ m_rolen = m_rlen = len;
+ if (!call Registers.getIeRx()) {
+ call Registers.clrIfgRx();
+ call Registers.setIeRx();
+ m_rxie = TRUE;
+ } else
+ m_rxie = FALSE;
+ }
+ }
+
+ async event void Interrupts.rx(uint8_t byte)
+ {
+ if (m_robuf) {
+ /* receive() takes precedence if active */
+ /* FIXME: an arbitrarily long ISR may occur if m_rlen is large.
+ * But depending on timing, we may always only read 1 byte.
+ */
+ while (m_rlen && call Registers.getIfgRx()) {
+ *m_rbuf = byte;
+ if (--m_rlen)
+ m_rbuf++;
+ }
+ if (m_rlen == 0 && m_robuf) {
+ if (m_rxie) {
+ call Registers.clrIeRx();
+ call Registers.clrIfgRx();
+ }
+ m_robuf = 0;
+ signal UartStream.receiveDone(m_robuf, m_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,
+ uclisten: FALSE,
+ 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 ) {}
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Header definitions for the USCI peripheral in newer msp430 processors.
+ * A USCI peripheral provides two communications devices, denoted A and B.
+ * Many parts have 2 USCI peripherals, denoted by 0 and 1. Therefore, a
+ * part with 2 USCI peripherals has 4 communications devices:
+ *
+ * USCI_A0 and USCI_B0, from the first USCI peripheral; and
+ * USCI_A1 and USCI_B1, from the second USCI peripheral.
+ *
+ * A devices offer UART, LIN, IrDA and SPI modes of operation. B parts are
+ * limited to SPI and I2C modes.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#ifndef MSP430_USCI_h
+#define MSP430_USCI_h
+
+#define MSP430_USCIA0_RESOURCE "Msp430UsciA0.Resource"
+#define MSP430_USCIB0_RESOURCE "Msp430UsciB0.Resource"
+#define MSP430_USCIA1_RESOURCE "Msp430UsciA1.Resource"
+#define MSP430_USCIB1_RESOURCE "Msp430UsciB1.Resource"
+
+typedef enum
+{
+ USCI_UART = 0,
+ USCI_SPI,
+ USCI_I2C
+} msp430_usci_mode_t;
+
+typedef enum {
+ USCI_REN_NONE = 0,
+
+ /* For use in UART mode */
+ USCI_REN_TX = 0x03,
+ USCI_REN_TX_PULLUP = 0x01,
+ USCI_REN_TX_PULLDOWN = 0x02,
+ USCI_REN_RX = 0x0c,
+ USCI_REN_RX_PULLUP = 0x04,
+ USCI_REN_RX_PULLDOWN = 0x08,
+
+ /* For use in SPI mode */
+ USCI_REN_STE = 0x30,
+ USCI_REN_STE_PULLUP = 0x10,
+ USCI_REN_STE_PULLDOWN = 0x20,
+ USCI_REN_SIMO = USCI_REN_TX,
+ USCI_REN_SIMO_PULLUP = USCI_REN_TX_PULLUP,
+ USCI_REN_SIMO_PULLDOWN = USCI_REN_TX_PULLDOWN,
+ USCI_REN_SOMI = USCI_REN_RX,
+ USCI_REN_SOMI_PULLUP = USCI_REN_RX_PULLUP,
+ USCI_REN_SOMI_PULLDOWN = USCI_REN_RX_PULLDOWN,
+ USCI_REN_CLK = 0xc0,
+ USCI_REN_CLK_PULLUP = 0x40,
+ USCI_REN_CLK_PULLDOWN = 0x80,
+
+ /* For use in I2C mode */
+ USCI_REN_SDA = USCI_REN_TX,
+ USCI_REN_SDA_PULLUP = USCI_REN_TX_PULLUP,
+ USCI_REN_SDA_PULLDOWN = USCI_REN_TX_PULLDOWN,
+ USCI_REN_SCL = USCI_REN_RX,
+ USCI_REN_SCL_PULLUP = USCI_REN_RX_PULLUP,
+ USCI_REN_SCL_PULLDOWN = USCI_REN_RX_PULLDOWN
+} msp430_ren_t;
+
+/* Baud rates for UART mode. Only 32KHz modes work right now. */
+typedef enum {
+ /* UCOS16=0. UMCTL = UCBRFx << 4 + UCBRSx << 1 + UCOS16.
+ * 1MHZ = 1,048576HZ, 1E6MHZ = 1,000,000HZ.
+ */
+ UBRX_32768HZ_9600=3, UMCTL_32768HZ_9600=(0 << 4) + (3 << 1) + 0,
+ UBRX_1MHZ_9600=109, UMCTL_1MHZ_9600=(0 << 4) + (2 << 1) + 0,
+ UBRX_1MHZ_19200=54, UMCTL_1MHZ_19200=(0 << 4) + (5 << 1) + 0,
+ UBRX_1MHZ_38400=27, UMCTL_1MHZ_38400=(0 << 4) + (2 << 1) + 0,
+ UBRX_1MHZ_115200=9, UMCTL_1MHZ_115200=(0 << 4) + (1 << 1) + 0,
+ UBRX_1E6MHZ_9600=104, UMCTL_1E6MHZ_9600=(0 << 4) + (1 << 1) + 0,
+ UBRX_1E6MHZ_115200=8, UMCTL_1E6MHZ_115200=(0 << 4) + (6 << 1) + 0,
+} msp430_usci_uart_rate_t;
+
+typedef struct {
+ uint8_t ctl0;
+ uint8_t ctl1;
+ uint16_t brx;
+ uint8_t mctl;
+ uint8_t irtctl;
+ uint8_t irrctl;
+ uint8_t abctl;
+ bool uclisten;
+ msp430_ren_t ren;
+} msp430_usci_uart_t;
+
+typedef struct {
+ uint8_t ctl0;
+ uint8_t ctl1;
+ uint16_t brx;
+ bool uclisten;
+ msp430_ren_t ren;
+} msp430_usci_spi_t;
+
+typedef struct {
+ uint8_t ctl0;
+ uint8_t ctl1;
+ uint16_t brx;
+ uint8_t i2cie;
+ uint8_t i2coa;
+ uint8_t i2csa;
+ bool uclisten;
+ msp430_ren_t ren;
+} msp430_usci_i2c_t;
+
+#endif
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Defines the USCI_A0 peripheral.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration Msp430UsciA0C {
+ provides {
+ interface HplMsp430UsciReg as Registers;
+ interface HplMsp430UsciInt as Interrupts[uint8_t];
+ interface Resource as Resource[uint8_t];
+ interface ResourceRequested as ResourceRequested[uint8_t];
+ interface ArbiterInfo;
+ }
+ uses interface ResourceConfigure as ResourceConfigure[uint8_t];
+}
+implementation {
+ components new FcfsArbiterC(MSP430_USCIA0_RESOURCE) as ArbiterC;
+ Resource = ArbiterC;
+ ResourceRequested = ArbiterC;
+ ResourceConfigure = ArbiterC;
+ ArbiterInfo = ArbiterC;
+
+ components new Msp430UsciIntDispatchP() as IntDispatchA0P;
+ Interrupts = IntDispatchA0P;
+ IntDispatchA0P.ArbiterInfo -> ArbiterC;
+
+ components HplMsp430UsciC as UsciC;
+ Registers = UsciC.RegA0;
+ IntDispatchA0P.RawInt -> UsciC.IntA0;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Defines the USCI_A1 peripheral.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration Msp430UsciA1C {
+ provides {
+ interface HplMsp430UsciReg as Registers;
+ interface HplMsp430UsciInt as Interrupts[uint8_t];
+ interface Resource as Resource[uint8_t];
+ interface ResourceRequested as ResourceRequested[uint8_t];
+ interface ArbiterInfo;
+ }
+ uses interface ResourceConfigure as ResourceConfigure[uint8_t];
+}
+implementation {
+ components new FcfsArbiterC(MSP430_USCIA1_RESOURCE) as ArbiterC;
+ Resource = ArbiterC;
+ ResourceRequested = ArbiterC;
+ ResourceConfigure = ArbiterC;
+ ArbiterInfo = ArbiterC;
+
+ components new Msp430UsciIntDispatchP() as IntDispatchA1P;
+ Interrupts = IntDispatchA1P;
+ IntDispatchA1P.ArbiterInfo -> ArbiterC;
+
+ components HplMsp430UsciC as UsciC;
+ Registers = UsciC.RegA1;
+ IntDispatchA1P.RawInt -> UsciC.IntA1;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Defines the USCI_B0 peripheral.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration Msp430UsciB0C {
+ provides {
+ interface HplMsp430UsciReg as Registers;
+ interface HplMsp430UsciInt as Interrupts[uint8_t];
+ interface Resource as Resource[uint8_t];
+ interface ResourceRequested as ResourceRequested[uint8_t];
+ interface ArbiterInfo;
+ }
+ uses interface ResourceConfigure as ResourceConfigure[uint8_t];
+}
+implementation {
+ components new FcfsArbiterC(MSP430_USCIB0_RESOURCE) as ArbiterC;
+ Resource = ArbiterC;
+ ResourceRequested = ArbiterC;
+ ResourceConfigure = ArbiterC;
+ ArbiterInfo = ArbiterC;
+
+ components new Msp430UsciIntDispatchP() as IntDispatchB0P;
+ Interrupts = IntDispatchB0P;
+ IntDispatchB0P.ArbiterInfo -> ArbiterC;
+
+ components HplMsp430UsciC as UsciC;
+ Registers = UsciC.RegB0;
+ IntDispatchB0P.RawInt -> UsciC.IntB0;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Defines the USCI_B1 peripheral.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+configuration Msp430UsciB1C {
+ provides {
+ interface HplMsp430UsciReg as Registers;
+ interface HplMsp430UsciInt as Interrupts[uint8_t];
+ interface Resource as Resource[uint8_t];
+ interface ResourceRequested as ResourceRequested[uint8_t];
+ interface ArbiterInfo;
+ }
+ uses interface ResourceConfigure as ResourceConfigure[uint8_t];
+}
+implementation {
+ components new FcfsArbiterC(MSP430_USCIB1_RESOURCE) as ArbiterC;
+ Resource = ArbiterC;
+ ResourceRequested = ArbiterC;
+ ResourceConfigure = ArbiterC;
+ ArbiterInfo = ArbiterC;
+
+ components new Msp430UsciIntDispatchP() as IntDispatchB1P;
+ Interrupts = IntDispatchB1P;
+ IntDispatchB1P.ArbiterInfo -> ArbiterC;
+
+ components HplMsp430UsciC as UsciC;
+ Registers = UsciC.RegB1;
+ IntDispatchB1P.RawInt -> UsciC.IntB1;
+}
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * Interrupt dispatch for USCI_Ax and USCI_Bx devices.
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+generic module Msp430UsciIntDispatchP() @safe() {
+ provides interface HplMsp430UsciInt as Interrupts[uint8_t id];
+ uses {
+ interface HplMsp430UsciInt as RawInt;
+ interface ArbiterInfo;
+ }
+}
+
+implementation {
+ async event void RawInt.brk()
+ {
+ if (call ArbiterInfo.inUse())
+ signal Interrupts.brk[call ArbiterInfo.userId()]();
+ }
+
+ async event void RawInt.rx(uint8_t byte)
+ {
+ if (call ArbiterInfo.inUse())
+ signal Interrupts.rx[call ArbiterInfo.userId()](byte);
+ }
+
+ async event void RawInt.tx()
+ {
+ if (call ArbiterInfo.inUse())
+ signal Interrupts.tx[call ArbiterInfo.userId()]();
+ }
+
+ async event void RawInt.i2cCal()
+ {
+ if (call ArbiterInfo.inUse())
+ signal Interrupts.i2cCal[call ArbiterInfo.userId()]();
+ }
+
+ async event void RawInt.i2cNak()
+ {
+ if (call ArbiterInfo.inUse())
+ signal Interrupts.i2cNak[call ArbiterInfo.userId()]();
+ }
+
+ async event void RawInt.i2cStart()
+ {
+ if (call ArbiterInfo.inUse())
+ signal Interrupts.i2cStart[call ArbiterInfo.userId()]();
+ }
+
+ async event void RawInt.i2cStop()
+ {
+ if (call ArbiterInfo.inUse())
+ signal Interrupts.i2cStop[call ArbiterInfo.userId()]();
+ }
+
+ default async event void Interrupts.brk[uint8_t id]() {}
+ default async event void Interrupts.rx[uint8_t id](uint8_t byte) {}
+ default async event void Interrupts.tx[uint8_t id]() {}
+ default async event void Interrupts.i2cCal[uint8_t id]() {}
+ default async event void Interrupts.i2cNak[uint8_t id]() {}
+ default async event void Interrupts.i2cStart[uint8_t id]() {}
+ default async event void Interrupts.i2cStop[uint8_t id]() {}
+}