From: R. Steve McKown Date: Wed, 2 Dec 2009 20:22:15 +0000 (-0700) Subject: SCP1000 pressure sensor chip support, SPI version. X-Git-Tag: patchset/2.1.1-4.5~17 X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=commitdiff_plain;h=2e460a6c49ab59c8fefcec0bbd3659135af918b6 SCP1000 pressure sensor chip support, SPI version. --- diff --git a/tos/chips/scp1000/Scp1000.h b/tos/chips/scp1000/Scp1000.h new file mode 100644 index 00000000..0fef9da3 --- /dev/null +++ b/tos/chips/scp1000/Scp1000.h @@ -0,0 +1,44 @@ +/* + * 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 SCP1000. + * + * @author R. Steve McKown + */ + +#ifndef SCP1000_H +#define SCP1000_H + +typedef struct { + unsigned int temp; + unsigned long pressure; +} scp1000_t; + +#endif diff --git a/tos/chips/scp1000/Scp1000C.nc b/tos/chips/scp1000/Scp1000C.nc new file mode 100644 index 00000000..f9be62f2 --- /dev/null +++ b/tos/chips/scp1000/Scp1000C.nc @@ -0,0 +1,59 @@ +/* + * 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. + */ + +/** + * Main user component for the SCP1000 pressure sensor. This is a highly + * abstracted component designed for infrequent pressure measurements where + * energy costs are to be minimized. + * + * @author R. Steve McKown + */ + +#include "Scp1000.h" + +configuration Scp1000C { + provides interface ReadRef; +} +implementation { + components new Scp1000P(); + ReadRef = Scp1000P; + + components Scp1000PinsC; + Scp1000P.CSn -> Scp1000PinsC.CSn; + Scp1000P.PD -> Scp1000PinsC.PD; + Scp1000P.DRDY -> Scp1000PinsC.DRDY; + Scp1000P.IntDRDY -> Scp1000PinsC; + + components Scp1000SpiC; + Scp1000P.Resource -> Scp1000SpiC; + Scp1000P.SpiByte -> Scp1000SpiC; + + components new TimerMilliC(); + Scp1000P.Timer -> TimerMilliC; +} diff --git a/tos/chips/scp1000/Scp1000P.nc b/tos/chips/scp1000/Scp1000P.nc new file mode 100644 index 00000000..7ff57aa9 --- /dev/null +++ b/tos/chips/scp1000/Scp1000P.nc @@ -0,0 +1,209 @@ +/* + * 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. + */ + +/** + * scp1000 implementation. + * + * @author R. Steve McKown + */ + +#include "Scp1000.h" + +generic module Scp1000P() @safe() +{ + provides interface ReadRef; + uses { + interface GeneralIO as CSn; + interface GeneralIO as PD; + interface GeneralIO as DRDY; + interface GpioInterrupt as IntDRDY; + interface Resource; + interface SpiByte; + interface Timer; + } +} +implementation +{ + enum { + /* Data register names for SCP1000 */ + OPERATION = 3, + STATUS = 7, + DATARD8 = 0x1f, + DATARD16 = 0x20, + TEMPOUT = 0x21, + + /* Timer states */ + TIMER_NONE = 0, + TIMER_POWER, + TIMER_CHECK, + TIMER_DRDY + }; + + scp1000_t* m_ptr; + uint8_t tstate; + uint8_t counter; + + inline uint8_t addrOut(uint8_t addr, bool write) + { + return (addr << 2) + (write ? 2 : 0); + } + + uint8_t readByte(uint8_t addr) + { + uint8_t data; + + call CSn.clr(); + call SpiByte.write(addrOut(addr, FALSE)); + data = call SpiByte.write(0); + call CSn.set(); + return data; + } + + void writeByte(uint8_t addr, uint8_t data) + { + call CSn.clr(); + call SpiByte.write(addrOut(addr, TRUE)); + call SpiByte.write(data); + call CSn.set(); + } + + uint16_t readWord(uint8_t addr) + { + uint16_t data; + + call CSn.clr(); + call SpiByte.write(addrOut(addr, FALSE)); + data = (call SpiByte.write(0) << 8); + data += call SpiByte.write(0); + call CSn.set(); + return data; + } + + void signalDone(error_t error) + { + scp1000_t* tmp = m_ptr; + + call PD.set(); + call Resource.release(); + m_ptr = 0; + signal ReadRef.readDone(error, tmp); + } + + command error_t ReadRef.read(scp1000_t* ptr) + { + if (m_ptr || !ptr) + return FAIL; + m_ptr = ptr; + call Resource.request(); + return SUCCESS; + } + + event void Resource.granted() + { + /* Begin powerup sequence */ + call PD.clr(); + tstate = TIMER_POWER; + call Timer.startOneShot(60); + } + + task void check() + { + /* Abort if we've waited too long for ready state */ + if (counter++ == 6) { + signalDone(FAIL); + return; + } + + /* Poll to see if the sensor is ready */ + if (readByte(STATUS) & 0x01) { + tstate = TIMER_CHECK; + call Timer.startOneShot(10); + return; + } + + /* Verify EEPROM was loaded without error */ + if (!(readByte(DATARD8) & 0x01)) { + signalDone(FAIL); + return; + } + + /* We could use the low noise configuration by also doing: + * writeByte(0x2d, 0x03); + * wait_ms(100); + * writeByte(OPERATION, 0); + * wait_ms(10); + * writeByte(OPERATION, 0x0a); -- 0x0a is high resolution mode + * wait_ms(100); + */ + + /* Initiate a reading. DRDY will assert when done, ~ 500ms from now */ + tstate = TIMER_DRDY; + call Timer.startOneShot(1024); + call IntDRDY.enableRisingEdge(); + writeByte(OPERATION, 0x0c); + } + + task void results(); + + async event void IntDRDY.fired() + { + call IntDRDY.disable(); + post results(); + } + + task void results() + { + call Timer.stop(); + m_ptr->temp = readWord(TEMPOUT); /* 20ths of a degree C */ + m_ptr->pressure = (uint32_t)readByte(DATARD8) << 16; + m_ptr->pressure += readWord(DATARD16); /* 4ths of a Pa? */ + signalDone(SUCCESS); + return; + } + + event void Timer.fired() + { + uint8_t tmp = tstate; + + tstate = TIMER_NONE; + switch (tmp) { + case TIMER_POWER: + counter = 0; + post check(); + break; + case TIMER_CHECK: + post check(); + break; + case TIMER_DRDY: + signalDone(FAIL); + break; + default: + } + } +}