]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/tosthreads/chips/atm128/HplAtm128SpiP.nc
Initial checkin of tosthreads stuff...
[tinyos-2.x.git] / tos / lib / tosthreads / chips / atm128 / HplAtm128SpiP.nc
diff --git a/tos/lib/tosthreads/chips/atm128/HplAtm128SpiP.nc b/tos/lib/tosthreads/chips/atm128/HplAtm128SpiP.nc
new file mode 100644 (file)
index 0000000..65073cf
--- /dev/null
@@ -0,0 +1,223 @@
+/// $Id$
+
+/*
+ * "Copyright (c) 2005 Stanford University. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the following two paragraphs and the author appear in all
+ * copies of this software.
+ * 
+ * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
+ * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2004-2005 Crossbow Technology, Inc.  All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL CROSSBOW TECHNOLOGY OR ANY OF ITS LICENSORS BE LIABLE TO 
+ * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL 
+ * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF CROSSBOW OR ITS LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
+ * DAMAGE. 
+ *
+ * CROSSBOW TECHNOLOGY AND ITS LICENSORS SPECIFICALLY DISCLAIM ALL WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 
+ * ON AN "AS IS" BASIS, AND NEITHER CROSSBOW NOR ANY LICENSOR HAS ANY 
+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 
+ * MODIFICATIONS.
+ */
+
+/**
+ * Implementation of the SPI bus abstraction for the atm128
+ * microcontroller.
+ *
+ * @author Philip Levis
+ * @author Martin Turon
+ */
+
+#include "Atm128Spi.h"
+
+module HplAtm128SpiP {
+  provides interface Atm128Spi as SPI;
+  provides interface AsyncStdControl;
+  
+  uses {
+    interface GeneralIO as SS;   // Slave set line
+    interface GeneralIO as SCK;  // SPI clock line
+    interface GeneralIO as MOSI; // Master out, slave in
+    interface GeneralIO as MISO; // Master in, slave out
+    interface McuPowerState as Mcu;
+    interface PlatformInterrupt;
+  }
+}
+implementation {
+
+  async command error_t AsyncStdControl.start() {
+    call SPI.enableSpi(TRUE);
+  }
+
+  async command error_t AsyncStdControl.stop() {
+    call SPI.enableInterrupt(FALSE);
+    call SPI.enableSpi(FALSE);
+  }
+  
+  async command void SPI.initMaster() {
+    call MOSI.makeOutput();
+    call MISO.makeInput();
+    call SCK.makeOutput();
+    call SPI.setMasterBit(TRUE);
+  }
+
+  async command void SPI.initSlave() {
+    call MISO.makeOutput();
+    call MOSI.makeInput();
+    call SCK.makeInput();
+    call SS.makeInput();
+    call SPI.setMasterBit(FALSE);
+  }
+  
+  async command void SPI.sleep() {
+//    call SS.set();   // why was this needed?
+  }
+  
+  async command uint8_t SPI.read()        { return SPDR; }
+  async command void SPI.write(uint8_t d) { SPDR = d; }
+    
+  default async event void SPI.dataReady(uint8_t d) {}
+  AVR_ATOMIC_HANDLER(SIG_SPI) {
+    signal SPI.dataReady(call SPI.read());
+    call PlatformInterrupt.postAmble();
+  }
+
+  //=== SPI Bus utility routines. ====================================
+  async command bool SPI.isInterruptPending() {
+    return READ_BIT(SPSR, SPIF);
+  }
+
+  async command bool SPI.isInterruptEnabled () {                
+    return READ_BIT(SPCR, SPIE);
+  }
+
+  async command void SPI.enableInterrupt(bool enabled) {
+    if (enabled) {
+      SET_BIT(SPCR, SPIE);
+      call Mcu.update();
+    }
+    else {
+      CLR_BIT(SPCR, SPIE);
+      call Mcu.update();
+    }
+  }
+
+  async command bool SPI.isSpiEnabled() {
+    return READ_BIT(SPCR, SPE);
+  }
+  
+  async command void SPI.enableSpi(bool enabled) {
+    if (enabled) {
+      SET_BIT(SPCR, SPE);
+      call Mcu.update();
+    }
+    else {
+      CLR_BIT(SPCR, SPE);
+      call Mcu.update();
+    }
+  }
+
+  /* DORD bit */
+  async command void SPI.setDataOrder(bool lsbFirst) {
+    if (lsbFirst) {
+      SET_BIT(SPCR, DORD);
+    }
+    else {
+      CLR_BIT(SPCR, DORD);
+    }
+  }
+  
+  async command bool SPI.isOrderLsbFirst() {
+    return READ_BIT(SPCR, DORD);
+  }
+  
+  /* MSTR bit */
+  async command void SPI.setMasterBit(bool isMaster) {
+    if (isMaster) {
+      SET_BIT(SPCR, MSTR);
+    }
+    else {
+      CLR_BIT(SPCR, MSTR);
+    }
+  }
+  async command bool SPI.isMasterBitSet() {
+    return READ_BIT(SPCR, MSTR);
+  }
+  
+  /* CPOL bit */
+  async command void SPI.setClockPolarity(bool highWhenIdle) {
+    if (highWhenIdle) {
+      SET_BIT(SPCR, CPOL);
+    }
+    else {
+      CLR_BIT(SPCR, CPOL);
+    }
+  }
+  
+  async command bool SPI.getClockPolarity() {
+    return READ_BIT(SPCR, CPOL);
+  }
+  
+  /* CPHA bit */
+  async command void SPI.setClockPhase(bool sampleOnTrailing) {
+    if (sampleOnTrailing) {
+      SET_BIT(SPCR, CPHA);
+    }
+    else {
+      CLR_BIT(SPCR, CPHA);
+    }
+  }
+  async command bool SPI.getClockPhase() {
+    return READ_BIT(SPCR, CPHA);
+  }
+
+  
+  async command uint8_t SPI.getClock () {                
+    return READ_FLAG(SPCR, ((1 << SPR1) | (1 <<SPR0)));
+  }
+  
+  async command void SPI.setClock (uint8_t v) {
+    v &= (SPR1) | (SPR0);
+    SPCR = (SPCR & ~(SPR1 | SPR0)) | v;
+  }
+
+  async command bool SPI.hasWriteCollided() {
+    return READ_BIT(SPSR, WCOL);
+  }
+
+  async command bool SPI.isMasterDoubleSpeed() {
+    return READ_BIT(SPSR, SPI2X);
+  }
+
+  async command void SPI.setMasterDoubleSpeed(bool on) {
+   if (on) {
+      SET_BIT(SPSR, SPI2X);
+    }
+    else {
+      CLR_BIT(SPSR, SPI2X);
+    }
+  }
+}