/**\r
- * Copyright (c) 2004-2005 Crossbow Technology, Inc.\r
+ * Copyright (c) 2005-2006 Crossbow Technology, Inc.\r
* All rights reserved.\r
*\r
* Permission to use, copy, modify, and distribute this software and its\r
* standard BSD license as contained in the TinyOS distribution.\r
*\r
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS \r
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, \r
- * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF \r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS\r
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,\r
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
* THE POSSIBILITY OF SUCH DAMAGE.\r
*\r
* @author Martin Turon <mturon@xbow.com>\r
- * @author Miguel Freitas\r
*\r
* $Id$\r
*/\r
/**\r
* This component is the "platform" of the sensorboard space.\r
* It handles particulars of initialization, and glues all the\r
- * member sensor "chips" into one place. The current implementation \r
- * is overly monolithic, and should be divided into smaller \r
+ * member sensor "chips" into one place. The current implementation\r
+ * is overly monolithic, and should be divided into smaller\r
* components that handle each individual sensor. The temperature\r
* and light sensors are tightly coupled however and in the case\r
* of the micaz, interfere with the radio (INT2), so more can\r
* be done to clean up the design here.\r
- * \r
+ *\r
* @author Martin Turon\r
* @date October 19, 2005\r
*/\r
module SensorMts300P\r
{\r
- provides {\r
- interface Init; //!< Standard Initialization\r
- interface StdControl; //!< Start/Stop for Power Management\r
- interface Read<uint16_t> as Temp; //!< Thermister\r
- interface Read<uint16_t> as Light; //!< Photo sensor\r
- }\r
+ provides\r
+ {\r
+ interface Init; //!< Standard Initialization\r
+ interface StdControl; //!< Start/Stop for Power Management\r
+ interface Read<uint16_t> as Vref; //!< voltage\r
+ interface Read<uint16_t> as Temp; //!< Thermister\r
+ interface Read<uint16_t> as Light; //!< Photo sensor\r
+ interface Read<uint16_t> as Microphone; //!< Mic sensor\r
+ interface Read<uint16_t> as AccelX; //!< Accelerometer sensor\r
+ interface Read<uint16_t> as AccelY; //!< Accelerometer sensor\r
+ interface Read<uint16_t> as MagX; //!< magnetometer sensor\r
+ interface Read<uint16_t> as MagY; //!< magnetometer sensor\r
+ }\r
\r
- uses {\r
- interface GeneralIO as TempPower;\r
- interface GeneralIO as LightPower;\r
- interface Read<uint16_t> as SensorADC;\r
- interface Timer<TMilli> as WarmUpTimer;\r
- }\r
+ uses\r
+ {\r
+ interface GeneralIO as TempPower;\r
+ interface GeneralIO as LightPower;\r
+ interface StdControl as PhotoControl;\r
+ interface StdControl as MicControl;\r
+ interface Mic;\r
+ interface StdControl as MagControl;\r
+ interface Mag;\r
+ interface StdControl as AccelControl;\r
+\r
+ interface Read<uint16_t> as VrefRead;\r
+ interface Read<uint16_t> as TempRead; //!< Thermister\r
+ interface Read<uint16_t> as LightRead; //!< Photo sensor\r
+ interface Read<uint16_t> as MicRead; //!< Mic sensor\r
+ interface Read<uint16_t> as AccelXRead; //!< Magnetometer sensor\r
+ interface Read<uint16_t> as AccelYRead; //!< Magnetometer sensor\r
+ interface Read<uint16_t> as MagXRead; //!< Magnetometer sensor\r
+ interface Read<uint16_t> as MagYRead; //!< Magnetometer sensor\r
+ interface Timer<TMilli> as WarmUpTimer;\r
+ }\r
}\r
-implementation \r
+implementation\r
{\r
- enum {\r
- STATE_IDLE = 0,\r
- STATE_LIGHT_WARMING, //!< Powering on sensor\r
- STATE_LIGHT_READY, //!< Power up of sensor complete\r
- STATE_LIGHT_SAMPLING, //!< Sampling sensor\r
- STATE_TEMP_WARMING, //!< Powering on sensor\r
- STATE_TEMP_READY, //!< Power up of sensor complete\r
- STATE_TEMP_SAMPLING, //!< Sampling sensor\r
- };\r
+ enum\r
+ {\r
+ STATE_IDLE = 0,\r
+ STATE_LIGHT_WARMING, //!< Powering on sensor\r
+ STATE_LIGHT_READY, //!< Power up of sensor complete\r
+ STATE_LIGHT_SAMPLING, //!< Sampling sensor\r
+ STATE_TEMP_WARMING, //!< Powering on sensor\r
+ STATE_TEMP_READY, //!< Power up of sensor complete\r
+ STATE_TEMP_SAMPLING, //!< Sampling sensor\r
+ STATE_MIC_WARMING, //!< Powering on sensor\r
+ STATE_MIC_READY, //!< Power up of sensor complete\r
+ STATE_MIC_SAMPLING, //!< Sampling sensor\r
+ };\r
\r
/// Yes, this could be a simple uint8_t. There used to be more bits here,\r
/// but they were optimized out and removed.\r
- union {\r
- uint8_t flat;\r
- struct {\r
+ union\r
+ {\r
+ uint8_t flat;\r
+ struct\r
+ {\r
uint8_t state : 4; //!< sensorboard state\r
- } bits;\r
- } g_flags;\r
+ } bits;\r
+ } g_flags;\r
\r
/**\r
* Initialize this component. Initialization should not assume that\r
* any component is running: init() cannot call any commands besides\r
- * those that initialize other components. \r
+ * those that initialize other components.\r
*\r
*/\r
- command error_t Init.init() {\r
- g_flags.flat = STATE_IDLE;\r
- return SUCCESS;\r
+ command error_t Init.init()\r
+ {\r
+ g_flags.flat = STATE_IDLE;\r
+ call Mic.muxSel(1); // Set the mux so that raw microhpone output is selected\r
+ call Mic.gainAdjust(64); // Set the gain of the microphone.\r
+\r
+ return SUCCESS;\r
}\r
\r
/**\r
*\r
* @return SUCCESS if the component was successfully started.\r
*/\r
- command error_t StdControl.start() {\r
- return SUCCESS;\r
+ command error_t StdControl.start()\r
+ {\r
+ call PhotoControl.start();\r
+ call MicControl.start();\r
+ call MagControl.start();\r
+ call AccelControl.start();\r
+ return SUCCESS;\r
}\r
- \r
+\r
/**\r
* Stop the component and pertinent subcomponents (not all\r
* subcomponents may be turned off due to wakeup timers, etc.).\r
*\r
* @return SUCCESS if the component was successfully stopped.\r
*/\r
- command error_t StdControl.stop() {\r
- call TempPower.clr();\r
- call LightPower.clr();\r
- call TempPower.makeInput();\r
- call LightPower.makeInput();\r
- atomic g_flags.bits.state = STATE_IDLE;\r
- return SUCCESS;\r
+ command error_t StdControl.stop()\r
+ {\r
+ call TempPower.clr();\r
+ call LightPower.clr();\r
+ call TempPower.makeInput();\r
+ call LightPower.makeInput();\r
+ atomic g_flags.bits.state = STATE_IDLE;\r
+\r
+ call PhotoControl.stop();\r
+ call MicControl.stop();\r
+ call MagControl.stop();\r
+ call AccelControl.stop();\r
+\r
+ return SUCCESS;\r
}\r
\r
/** Turns on the light sensor and turns the thermistor off. */\r
- void switchLightOn() {\r
- atomic g_flags.bits.state = STATE_LIGHT_WARMING;\r
- call TempPower.clr();\r
- call TempPower.makeInput();\r
- call LightPower.makeOutput();\r
- call LightPower.set();\r
- call WarmUpTimer.startOneShot(10);\r
+ void switchLightOn()\r
+ {\r
+ atomic g_flags.bits.state = STATE_LIGHT_WARMING;\r
+ call TempPower.clr();\r
+ call TempPower.makeInput();\r
+ call LightPower.makeOutput();\r
+ call LightPower.set();\r
+ call WarmUpTimer.startOneShot(10);\r
}\r
\r
/** Turns on the thermistor and turns the light sensor off. */\r
- void switchTempOn() {\r
- atomic g_flags.bits.state = STATE_TEMP_WARMING;\r
- call LightPower.clr();\r
- call LightPower.makeInput();\r
- call TempPower.makeOutput();\r
- call TempPower.set();\r
- call WarmUpTimer.startOneShot(10);\r
+ void switchTempOn()\r
+ {\r
+ atomic g_flags.bits.state = STATE_TEMP_WARMING;\r
+ call LightPower.clr();\r
+ call LightPower.makeInput();\r
+ call TempPower.makeOutput();\r
+ call TempPower.set();\r
+ call WarmUpTimer.startOneShot(10);\r
}\r
\r
- task void getLightSample() {\r
- switch (g_flags.bits.state) {\r
- case STATE_TEMP_WARMING:\r
- case STATE_TEMP_READY:\r
- case STATE_TEMP_SAMPLING:\r
- // If Temperature is busy, repost and try again later.\r
- // This will not let the CPU sleep. Add delay timer.\r
- post getLightSample();\r
- return;\r
-\r
- case STATE_IDLE: \r
- // Okay, grab the sensor.\r
- switchLightOn();\r
- return;\r
- \r
- case STATE_LIGHT_WARMING:\r
- // Warm-up Timer will switch out of this state.\r
- return;\r
-\r
- case STATE_LIGHT_READY:\r
- // Start the sample.\r
- atomic { g_flags.bits.state = STATE_LIGHT_SAMPLING; }\r
- call SensorADC.read();\r
- return;\r
+ void switchMicOn()\r
+ {\r
+ atomic g_flags.bits.state = STATE_MIC_WARMING;\r
+ call WarmUpTimer.startOneShot(10);\r
+ }\r
\r
- case STATE_LIGHT_SAMPLING:\r
- // SensorADC.dataReady will switch out of this state.\r
- return;\r
- }\r
+ task void getLightSample()\r
+ {\r
+ switch (g_flags.bits.state)\r
+ {\r
+ case STATE_IDLE:\r
+ // Okay, grab the sensor.\r
+ switchLightOn();\r
+ return;\r
+ case STATE_LIGHT_READY:\r
+ // Start the sample.\r
+ atomic { g_flags.bits.state = STATE_LIGHT_SAMPLING; }\r
+ call LightRead.read();\r
+ return;\r
+ case STATE_LIGHT_WARMING:\r
+ // Warm-up Timer will switch out of this state.\r
+ case STATE_LIGHT_SAMPLING:\r
+ // LightRead.readDone will switch out of this state.\r
+ return;\r
+ }\r
}\r
\r
- task void getTempSample() {\r
- switch (g_flags.bits.state) {\r
- case STATE_LIGHT_WARMING:\r
- case STATE_LIGHT_READY:\r
- case STATE_LIGHT_SAMPLING:\r
- // If Temperature is busy, repost and try again later.\r
- // This will not let the CPU sleep. Add delay timer.\r
- post getTempSample();\r
- return;\r
-\r
- case STATE_IDLE: \r
- // Okay, grab the sensor.\r
- switchTempOn();\r
- return;\r
- \r
- case STATE_TEMP_WARMING:\r
- // Warm-up Timer will switch out of this state.\r
- return;\r
-\r
- case STATE_TEMP_READY:\r
- // Start the sample.\r
- atomic { g_flags.bits.state = STATE_TEMP_SAMPLING; }\r
- call SensorADC.read();\r
- return;\r
+ task void getTempSample()\r
+ {\r
+ switch (g_flags.bits.state)\r
+ {\r
+ case STATE_IDLE:\r
+ // Okay, grab the sensor.\r
+ switchTempOn();\r
+ return;\r
+ case STATE_TEMP_READY:\r
+ // Start the sample.\r
+ atomic { g_flags.bits.state = STATE_TEMP_SAMPLING; }\r
+ call TempRead.read();\r
+ return;\r
+ case STATE_TEMP_WARMING:\r
+ // Warm-up Timer will switch out of this state.\r
+ case STATE_TEMP_SAMPLING:\r
+ // TempRead.readDone will switch out of this state.\r
+ return;\r
+ }\r
+ }\r
\r
- case STATE_TEMP_SAMPLING:\r
- // SensorADC.dataReady will switch out of this state.\r
- return;\r
- }\r
+ task void getMicSample()\r
+ {\r
+ switch (g_flags.bits.state)\r
+ {\r
+ case STATE_IDLE:\r
+ // Okay, grab the sensor.\r
+ switchMicOn();\r
+ return;\r
+ case STATE_MIC_READY:\r
+ // Start the sample.\r
+ atomic { g_flags.bits.state = STATE_MIC_SAMPLING; }\r
+ call MicRead.read();\r
+ return;\r
+ case STATE_MIC_WARMING:\r
+ // Warm-up Timer will switch out of this state.\r
+ case STATE_MIC_SAMPLING:\r
+ // MicRead.readDone will switch out of this state.\r
+ return;\r
+ }\r
}\r
\r
- /** \r
- * Start Temperature data acquisition. \r
+ /**\r
+ * Start Temperature data acquisition.\r
*\r
* This will post a task which will handle sequential states:\r
* WARMING, READY, SAMPLING, DONE (IDLE)\r
* @return SUCCESS if request accepted, EBUSY if it is refused\r
* 'dataReady' or 'error' will be signaled if SUCCESS is returned\r
*/\r
- command error_t Temp.read() {\r
- post getTempSample(); \r
- return SUCCESS;\r
+ command error_t Temp.read()\r
+ {\r
+ post getTempSample();\r
+ return SUCCESS;\r
}\r
-\r
- /** \r
- * Start Light data acquisition.\r
- *\r
- * This will post a task which will handle sequential states:\r
- * WARMING, READY, SAMPLING, DONE (IDLE)\r
- * and repost itself until it is completed.\r
- *\r
- * @return SUCCESS if request accepted, EBUSY if it is refused\r
- * 'dataReady' or 'error' will be signaled if SUCCESS is returned\r
- */\r
- command error_t Light.read() {\r
- post getLightSample(); \r
- return SUCCESS;\r
+ command error_t Light.read()\r
+ {\r
+ post getLightSample();\r
+ return SUCCESS;\r
}\r
-\r
- /** \r
+ command error_t Microphone.read()\r
+ {\r
+ post getMicSample();\r
+ return SUCCESS;\r
+ }\r
+ command error_t Vref.read()\r
+ {\r
+ call VrefRead.read();\r
+ return SUCCESS;\r
+ }\r
+ command error_t AccelX.read()\r
+ {\r
+ //signal AccelX.readDone(SUCCESS,0x1);\r
+ call AccelXRead.read();\r
+ return SUCCESS;\r
+ }\r
+ command error_t AccelY.read()\r
+ {\r
+ //signal AccelY.readDone(SUCCESS,0x2);\r
+ call AccelYRead.read();\r
+ return SUCCESS;\r
+ }\r
+ command error_t MagX.read()\r
+ {\r
+ //signal MagX.readDone(SUCCESS,0x3);\r
+ call MagXRead.read();\r
+ return SUCCESS;\r
+ }\r
+ command error_t MagY.read()\r
+ {\r
+ //signal MagY.readDone(SUCCESS,0x4);\r
+ call MagYRead.read();\r
+ return SUCCESS;\r
+ }\r
+ /**\r
* Timer to allow either thermistor or light sensor to warm up for 10 msec.\r
*/\r
- event void WarmUpTimer.fired() {\r
- switch (g_flags.bits.state) {\r
- case STATE_LIGHT_WARMING:\r
- atomic { g_flags.bits.state = STATE_LIGHT_READY; }\r
- post getLightSample();\r
- return;\r
-\r
- case STATE_TEMP_WARMING:\r
- atomic { g_flags.bits.state = STATE_TEMP_READY; }\r
- post getTempSample();\r
- return;\r
-\r
- default:\r
- //ERROR!!!\r
- signal Light.readDone( FAIL, 0 );\r
- signal Temp.readDone( FAIL, 0 );\r
- }\r
- // Worst case -- return to the IDLE state so next task can progress !!\r
- atomic { g_flags.bits.state = STATE_IDLE; }\r
+ event void WarmUpTimer.fired()\r
+ {\r
+ switch (g_flags.bits.state)\r
+ {\r
+ case STATE_LIGHT_WARMING:\r
+ atomic { g_flags.bits.state = STATE_LIGHT_READY; }\r
+ post getLightSample();\r
+ return;\r
+\r
+ case STATE_TEMP_WARMING:\r
+ atomic { g_flags.bits.state = STATE_TEMP_READY; }\r
+ post getTempSample();\r
+ return;\r
+\r
+ case STATE_MIC_WARMING:\r
+ atomic { g_flags.bits.state = STATE_MIC_READY; }\r
+ post getMicSample();\r
+ return;\r
+\r
+ default:\r
+ //ERROR!!!\r
+ signal Light.readDone(FAIL,0);\r
+ signal Temp.readDone(FAIL,0);\r
+ signal Microphone.readDone(FAIL,0);\r
+ }\r
+ // Worst case -- return to the IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
}\r
\r
- /** \r
+ /**\r
* Data has been acquired.\r
- * @param data Acquired value\r
- * Values are "left-justified" within each 16-bit integer, i.e., if\r
- * the data is acquired with n bits of precision, each value is \r
- * shifted left by 16-n bits.\r
+ * @param result Acquired success flag\r
+ * @param val Acquired value\r
*/\r
- event void SensorADC.readDone( error_t result, uint16_t data ) {\r
- switch (g_flags.bits.state) {\r
+ event void LightRead.readDone( error_t result, uint16_t val )\r
+ {\r
+ //val = (val >>6);\r
+ val &= 0x3ff;\r
+ switch (g_flags.bits.state)\r
+ {\r
case STATE_LIGHT_SAMPLING:\r
- signal Light.readDone(result, data);\r
- break;\r
+ signal Light.readDone(result,val);\r
+ break;\r
+ default: //ERROR!!!\r
+ signal Light.readDone(FAIL,0);\r
+ }\r
+ // state must return to IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
+ }\r
\r
+ event void TempRead.readDone( error_t result, uint16_t val )\r
+ {\r
+ //val = (val >>6);\r
+ val &= 0x3ff;\r
+ switch (g_flags.bits.state)\r
+ {\r
case STATE_TEMP_SAMPLING:\r
- signal Temp.readDone(result, data);\r
- break;\r
-\r
- default:\r
- //ERROR!!!\r
- signal Light.readDone( FAIL, 0 );\r
- signal Temp.readDone( FAIL, 0 );\r
- }\r
- // ADC.dataReady must return to IDLE state so next task can progress !!\r
- atomic { g_flags.bits.state = STATE_IDLE; }\r
+ signal Temp.readDone(result,val);\r
+ break;\r
+ default: //ERROR!!!\r
+ signal Temp.readDone(FAIL,0);\r
+ }\r
+ // state must return to IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
}\r
\r
+ event void MicRead.readDone( error_t result, uint16_t val )\r
+ {\r
+ //val = (val >>6);\r
+ val &= 0x3ff;\r
+ switch (g_flags.bits.state)\r
+ {\r
+ case STATE_MIC_SAMPLING:\r
+ signal Microphone.readDone(result,val);\r
+ break;\r
+ default: //ERROR!!!\r
+ signal Microphone.readDone(FAIL,0);\r
+ }\r
+ // state must return to IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
+ }\r
+\r
+ event void VrefRead.readDone( error_t result, uint16_t val )\r
+ {\r
+ //val = (val >>6);\r
+ val &= 0x3ff;\r
+ signal Vref.readDone(result,val);\r
+ // state must return to IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
+ }\r
+\r
+ event void AccelXRead.readDone( error_t result, uint16_t val )\r
+ {\r
+ //val = (val >>6);\r
+ val &= 0x3ff;\r
+ signal AccelX.readDone(result,val);\r
+ // state must return to IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
+ }\r
+\r
+ event void AccelYRead.readDone( error_t result, uint16_t val )\r
+ {\r
+ //val = (val >>6);\r
+ val &= 0x3ff;\r
+ signal AccelY.readDone(result,val);\r
+ // state must return to IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
+ }\r
+\r
+ event void MagXRead.readDone( error_t result, uint16_t val )\r
+ {\r
+ //val = (val >>6);\r
+ val &= 0x3ff;\r
+ signal MagX.readDone(result,val);\r
+ // state must return to IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
+ }\r
+\r
+ event void MagYRead.readDone( error_t result, uint16_t val )\r
+ {\r
+ //val = (val >>6);\r
+ val &= 0x3ff;\r
+ signal MagY.readDone(result,val);\r
+ // state must return to IDLE state so next task can progress !!\r
+ atomic { g_flags.bits.state = STATE_IDLE; }\r
+ }\r
+\r
+ event error_t Mag.gainAdjustXDone(bool result)\r
+ {\r
+ return result;\r
+ }\r
+ event error_t Mag.gainAdjustYDone(bool result)\r
+ {\r
+ return result;\r
+ }\r
}\r
\r
\r
\r
+\r
+\r