Revision 1:acdf490d94a7, committed 2014-04-08
- Comitter:
- marcelobarrosalmeida
- Date:
- Tue Apr 08 16:34:20 2014 +0000
- Parent:
- 0:01c4d4d8febf
- Commit message:
- Adding accel to sensor list
Changed in this revision
diff -r 01c4d4d8febf -r acdf490d94a7 MMA8451Q/MMA8451Q.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA8451Q/MMA8451Q.cpp Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,81 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "MMA8451Q.h"
+
+#define REG_WHO_AM_I 0x0D
+#define REG_CTRL_REG_1 0x2A
+#define REG_OUT_X_MSB 0x01
+#define REG_OUT_Y_MSB 0x03
+#define REG_OUT_Z_MSB 0x05
+
+#define UINT14_MAX 16383
+
+MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
+ // activate the peripheral
+ uint8_t data[2] = {REG_CTRL_REG_1, 0x01};
+ writeRegs(data, 2);
+}
+
+MMA8451Q::~MMA8451Q() { }
+
+uint8_t MMA8451Q::getWhoAmI() {
+ uint8_t who_am_i = 0;
+ readRegs(REG_WHO_AM_I, &who_am_i, 1);
+ return who_am_i;
+}
+
+float MMA8451Q::getAccX() {
+ return (float(getAccAxis(REG_OUT_X_MSB))/4096.0);
+}
+
+float MMA8451Q::getAccY() {
+ return (float(getAccAxis(REG_OUT_Y_MSB))/4096.0);
+}
+
+float MMA8451Q::getAccZ() {
+ return (float(getAccAxis(REG_OUT_Z_MSB))/4096.0);
+}
+
+void MMA8451Q::getAccAllAxis(float * res) {
+ res[0] = getAccX();
+ res[1] = getAccY();
+ res[2] = getAccZ();
+}
+
+int16_t MMA8451Q::getAccAxis(uint8_t addr) {
+ int16_t acc;
+ uint8_t res[2];
+ readRegs(addr, res, 2);
+
+ acc = (res[0] << 6) | (res[1] >> 2);
+ if (acc > UINT14_MAX/2)
+ acc -= UINT14_MAX;
+
+ return acc;
+}
+
+void MMA8451Q::readRegs(int addr, uint8_t * data, int len) {
+ char t[1] = {addr};
+ m_i2c.write(m_addr, t, 1, true);
+ m_i2c.read(m_addr, (char *)data, len);
+}
+
+void MMA8451Q::writeRegs(uint8_t * data, int len) {
+ m_i2c.write(m_addr, (char *)data, len);
+}
diff -r 01c4d4d8febf -r acdf490d94a7 MMA8451Q/MMA8451Q.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA8451Q/MMA8451Q.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,110 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef MMA8451Q_H
+#define MMA8451Q_H
+
+#include "mbed.h"
+
+/**
+* MMA8451Q accelerometer example
+*
+* @code
+* #include "mbed.h"
+* #include "MMA8451Q.h"
+*
+* #define MMA8451_I2C_ADDRESS (0x1d<<1)
+*
+* int main(void) {
+*
+* MMA8451Q acc(P_E25, P_E24, MMA8451_I2C_ADDRESS);
+* PwmOut rled(LED_RED);
+* PwmOut gled(LED_GREEN);
+* PwmOut bled(LED_BLUE);
+*
+* while (true) {
+* rled = 1.0 - abs(acc.getAccX());
+* gled = 1.0 - abs(acc.getAccY());
+* bled = 1.0 - abs(acc.getAccZ());
+* wait(0.1);
+* }
+* }
+* @endcode
+*/
+class MMA8451Q
+{
+public:
+ /**
+ * MMA8451Q constructor
+ *
+ * @param sda SDA pin
+ * @param sdl SCL pin
+ * @param addr addr of the I2C peripheral
+ */
+ MMA8451Q(PinName sda, PinName scl, int addr);
+
+ /**
+ * MMA8451Q destructor
+ */
+ ~MMA8451Q();
+
+ /**
+ * Get the value of the WHO_AM_I register
+ *
+ * @returns WHO_AM_I value
+ */
+ uint8_t getWhoAmI();
+
+ /**
+ * Get X axis acceleration
+ *
+ * @returns X axis acceleration
+ */
+ float getAccX();
+
+ /**
+ * Get Y axis acceleration
+ *
+ * @returns Y axis acceleration
+ */
+ float getAccY();
+
+ /**
+ * Get Z axis acceleration
+ *
+ * @returns Z axis acceleration
+ */
+ float getAccZ();
+
+ /**
+ * Get XYZ axis acceleration
+ *
+ * @param res array where acceleration data will be stored
+ */
+ void getAccAllAxis(float * res);
+
+private:
+ I2C m_i2c;
+ int m_addr;
+ void readRegs(int addr, uint8_t * data, int len);
+ void writeRegs(uint8_t * data, int len);
+ int16_t getAccAxis(uint8_t addr);
+
+};
+
+#endif
diff -r 01c4d4d8febf -r acdf490d94a7 SLCD.lib
--- a/SLCD.lib Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/users/Sissors/code/SLCD/#dc8a41707598
diff -r 01c4d4d8febf -r acdf490d94a7 SLCD/FRDM-s401.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLCD/FRDM-s401.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,96 @@
+/*^^^^^^^^^^^^^^^^ LCD HARDWARE CONECTION ^^^^^^^^^^^^^^^^^^^^^^^^*/
+#define _LCDFRONTPLANES (8) // # of frontPlanes
+#define _LCDBACKPLANES (4) // # of backplanes
+
+/*
+ LCD logical organization definition
+ This section indicates how the LCD is distributed how many characteres of (7-seg, 14,seg, 16 seg, or colums in case of Dot Matrix) does it contain
+ First character is forced only one can be written
+
+*/
+// HARDWARE_CONFIG Changing LCD pins Allows to verify all LCD pins easily
+// if HARDWARE_CONFIG == 0 FRDM-KL46 RevB
+// if HARDWARE_CONFIG == 1 FRDM-KL46 RevA
+#ifdef FRDM_REVA
+#define HARDWARE_CONFIG 1
+#else
+#define HARDWARE_CONFIG 0
+#endif
+
+#define _CHARNUM (4) //number of chars that can be written
+#define _CHAR_SIZE (2) // Used only when Dot Matrix is used
+#define _LCDTYPE (2) //indicate how many LCD_WF are required to write a single Character
+
+/*
+ Following definitions indicate how characters are associated to waveform
+*/
+/* Hardware configuration */
+#if HARDWARE_CONFIG == 0
+
+// LCD PIN1 to LCDWF0 Rev B
+#define CHAR1a 37 // LCD Pin 5
+#define CHAR1b 17 // LCD Pin 6
+#define CHAR2a 7 // LCD Pin 7
+#define CHAR2b 8 // LCD Pin 8
+#define CHAR3a 53 // LCD Pin 9
+#define CHAR3b 38 // LCD Pin 10
+#define CHAR4a 10 // LCD Pin 11
+#define CHAR4b 11 // LCD Pin 12
+#define CHARCOM0 40 // LCD Pin 1
+#define CHARCOM1 52 // LCD Pin 2
+#define CHARCOM2 19 // LCD Pin 3
+#define CHARCOM3 18 // LCD Pin 4
+
+// LCD PIN1 to LCDWF2 for FRDM-KL46Z
+#elif HARDWARE_CONFIG == 1
+#define CHAR1a 37 // LCD Pin 5
+#define CHAR1b 17 // LCD Pin 6
+#define CHAR2a 7 // LCD Pin 7
+#define CHAR2b 8 // LCD Pin 8
+#define CHAR3a 12 // LCD Pin 9
+#define CHAR3b 26 // LCD Pin 10
+#define CHAR4a 10 // LCD Pin 11
+#define CHAR4b 11 // LCD Pin 12
+#define CHARCOM0 51 // LCD Pin 1
+#define CHARCOM1 52 // LCD Pin 2
+#define CHARCOM2 19 // LCD Pin 3
+#define CHARCOM3 16 // LCD Pin 4
+
+#endif
+
+
+/*Ascii Codification table information */
+#define ASCCI_TABLE_START '0' // indicates which is the first Ascii character in the table
+#define ASCCI_TABLE_END 'Z' // indicates which is the last Ascii character in the table
+#define BLANK_CHARACTER '>' // Indicate which ASCII character is a blank character (depends on ASCII table)
+
+#define _ALLON 0xFF // Used for ALL_on function
+
+#define SEGDP 0x01
+#define SEGC 0x02
+#define SEGB 0x04
+#define SEGA 0x08
+
+#define SEGD 0x01
+#define SEGE 0x02
+#define SEGG 0x04
+#define SEGF 0x08
+
+
+/* Fault detect initial limits */
+
+/* Fault detect initial parameters and limits */
+#define FAULTD_FP_FDPRS FDPRS_32
+#define FAULTD_FP_FDSWW FDSWW_128
+#define FAULTD_BP_FDPRS FDPRS_64
+#define FAULTD_BP_FDSWW FDSWW_128
+
+#define FAULTD_FP_HI 127
+#define FAULTD_FP_LO 110
+#define FAULTD_BP_HI 127
+#define FAULTD_BP_LO 110
+#define FAULTD_TIME 6
+
+extern const uint8_t WF_ORDERING_TABLE[]; // Logical Front plane N to LCD_WFx
+
+
diff -r 01c4d4d8febf -r acdf490d94a7 SLCD/LCDconfig.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLCD/LCDconfig.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,183 @@
+#include "FRDM-s401.h" // 4x7 segdisplay
+
+
+#if 1 // VREF to VLL1
+/* Following configuration is used for LCD default initialization */
+#define _LCDRVEN (1) //
+#define _LCDRVTRIM (8) // CPSEL = 1 0 -- 8000 pf 1 -- 6000 pf 2 -- 4000 pf 3 -- 2000 pf
+#define _LCDCPSEL (1) // charge pump select 0 or 1
+#define _LCDLOADADJUST (3) // CPSEL = 1 0 -- 8000 pf 1 -- 6000 pf 2 -- 4000 pf 3 -- 2000 pf
+#define _LCDALTDIV (0) // CPSEL = 1 0 -- 8000 pf 1 -- 6000 pf 2 -- 4000 pf 3 -- 2000 pf
+#define _LCDALRCLKSOURCE (0) // 0 -- External clock 1 -- Alternate clock
+
+#define _LCDCLKPSL (0) // Clock divider to generate the LCD Waveforms
+#define _LCDSUPPLY (1)
+#define _LCDHREF (0) // 0 or 1
+#define _LCDCLKSOURCE (1) // 0 -- External clock 1 -- Alternate clock
+#define _LCDLCK (1) //Any number between 0 and 7
+#define _LCDBLINKRATE (3) //Any number between 0 and 7
+
+
+#else //VLL3 to VDD internally
+/* Following configuration is used for LCD default initialization */
+#define _LCDCLKSOURCE (1) // 0 -- External clock 1 -- Alternate clock
+#define _LCDALRCLKSOURCE (0) // 0 -- External clock 1 -- Alternate clock
+#define _LCDCLKPSL (0) // Clock divider to generate the LCD Waveforms
+#define _LCDSUPPLY (0)
+#define _LCDLOADADJUST (3) // CPSEL = 1 0 -- 8000 pf 1 -- 6000 pf 2 -- 4000 pf 3 -- 2000 pf
+#define _LCDALTDIV (0) // CPSEL = 1 0 -- 8000 pf 1 -- 6000 pf 2 -- 4000 pf 3 -- 2000 pf
+#define _LCDRVTRIM (0) // CPSEL = 1 0 -- 8000 pf 1 -- 6000 pf 2 -- 4000 pf 3 -- 2000 pf
+#define _LCDHREF (0) // 0 or 1
+#define _LCDCPSEL (1) // 0 or 1
+#define _LCDRVEN (0) //
+#define _LCDBLINKRATE (3) // Any number between 0 and 7
+#define _LCDLCK (0) // Any number between 0 and 7
+
+#endif
+
+
+
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~ LCD Control Register 0 ~|~|~|~|~|~|~|~|~|~|~|~|~*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDINTENABLE (1)
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~ LCD Control Register 1 ~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDFRAMEINTERRUPT (0) //0 Disable Frame Frequency Interrupt
+ //1 Enable an LCD interrupt that coincides with the LCD frame frequency
+#define _LCDFULLCPLDIRIVE (0) // 0 GPIO shared with the LCD. Inputs levels and internal pullup reference to VDD
+ // 1 If VSUPPLY=11and RVEN=0. Inputs levels and internal pullup reference to VLL3
+#define _LCDWAITMODE (0) // 0 Allows the LCD driver and charge pump to continue running during wait mode
+ // 1 Disable the LCD when the MCU goes into wait mode
+#define _LCDSTOPMODE (0) // 0 Allows the LCD driver and charge pump to continue running during stop2 or stop3
+ // 1 Disable the LCD when and charge pump when the MCU goes into stop2 or stop3
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~ LCD Voltage Supply Register ~|~|~|~|~|~|~|~|~|~|~|~*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDHIGHREF (0) //0 Divide input VIREG=1.0v
+ //1 Do not divide the input VIREG=1.67v
+#define _LCDBBYPASS (0) //Determines whether the internal LCD op amp buffer is bypassed
+ //0 Buffered mode
+ //1 Unbuffered mode
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~ LCD Regulated Voltage Control |~|~|~|~|~|~|~|~|~|~*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDCONTRAST (1) //Contrast by software 0 -- Disable 1-- Enable
+#define _LVLCONTRAST (0) //Any number between 0 and 15, if the number is bigger the glass gets darker
+
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~ LCD Blink Control Register ~|~|~|~|~|~|~|~|~|~|~|~*/
+/*~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|*/
+#define _LCDBLINKCONTROL (1) //0 Disable blink mode
+ //1 Enable blink mode
+#define _LCDALTMODE (0) //0 Normal display
+ //1 Alternate display for 4 backplanes or less the LCD backplane sequencer changes to otuput an alternate display
+#define _LCDBLANKDISP (0) //0 Do not blank display
+ //1 Blank display if you put it in 0 the text before blank is manteined
+#define _LCDBLINKMODE (0) //0 Display blank during the blink period
+ //1 Display alternate displat during blink period (Ignored if duty is 5 or greater)
+
+
+//Calculated values
+#define _LCDUSEDPINS (_LCDFRONTPLANES + _LCDBACKPLANES)
+#define _LCDDUTY (_LCDBACKPLANES-1) //Any number between 0 and 7
+#define LCD_WF_BASE LCD->WF8B[0]
+
+// General definitions used by the LCD library
+#define LCD_WF(x) *((uint8 *)&LCD_WF_BASE + x)
+
+/*LCD Fault Detections Consts*/
+#define FP_TYPE 0x00 // pin is a Front Plane
+#define BP_TYPE 0x80 // pin is Back Plane
+
+// Fault Detect Preescaler Options
+#define FDPRS_1 0
+#define FDPRS_2 1
+#define FDPRS_4 2
+#define FDPRS_8 3
+#define FDPRS_16 4
+#define FDPRS_32 5
+#define FDPRS_64 6
+#define FDPRS_128 7
+
+// Fault Detect Sample Window Width Values
+#define FDSWW_4 0
+#define FDSWW_8 1
+#define FDSWW_16 2
+#define FDSWW_32 3
+#define FDSWW_64 4
+#define FDSWW_128 5
+#define FDSWW_256 6
+#define FDSWW_512 7
+
+/*
+ Mask Bit definitions used f
+*/
+#define mBIT0 1
+#define mBIT1 2
+#define mBIT2 4
+#define mBIT3 8
+#define mBIT4 16
+#define mBIT5 32
+#define mBIT6 64
+#define mBIT7 128
+#define mBIT8 256
+#define mBIT9 512
+#define mBIT10 1024
+#define mBIT11 2048
+#define mBIT12 4096
+#define mBIT13 8192
+#define mBIT14 16384
+#define mBIT15 32768
+#define mBIT16 65536
+#define mBIT17 131072
+#define mBIT18 262144
+#define mBIT19 524288
+#define mBIT20 1048576
+#define mBIT21 2097152
+#define mBIT22 4194304
+#define mBIT23 8388608
+#define mBIT24 16777216
+#define mBIT25 33554432
+#define mBIT26 67108864
+#define mBIT27 134217728
+#define mBIT28 268435456
+#define mBIT29 536870912
+#define mBIT30 1073741824
+#define mBIT31 2147483648
+
+#define mBIT32 1
+#define mBIT33 2
+#define mBIT34 4
+#define mBIT35 8
+#define mBIT36 16
+#define mBIT37 32
+#define mBIT38 64
+#define mBIT39 128
+#define mBIT40 256
+#define mBIT41 512
+#define mBIT42 1024
+#define mBIT43 2048
+#define mBIT44 4096
+#define mBIT45 8192
+#define mBIT46 16384
+#define mBIT47 32768
+#define mBIT48 65536
+#define mBIT49 131072
+#define mBIT50 262144
+#define mBIT51 524288
+#define mBIT52 1048576
+#define mBIT53 2097152
+#define mBIT54 4194304
+#define mBIT55 8388608
+#define mBIT56 16777216
+#define mBIT57 33554432
+#define mBIT58 67108864
+#define mBIT59 134217728
+#define mBIT60 268435456
+#define mBIT61 536870912
+#define mBIT62 1073741824
+#define mBIT63 2147483648
+
+
+
diff -r 01c4d4d8febf -r acdf490d94a7 SLCD/SLCD.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLCD/SLCD.cpp Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,243 @@
+#include "SLCD.h"
+#include "LCDconfig.h"
+
+
+const uint8_t WF_ORDERING_TABLE[ ] =
+{
+ CHAR1a, // LCD81 --- Pin:5 LCDnAddress=51
+ CHAR1b, // LCD82 --- Pin:6 LCDnAddress=52
+ CHAR2a, // LCD83 --- Pin:7 LCDnAddress=53
+ CHAR2b, // LCD84 --- Pin:8 LCDnAddress=54
+ CHAR3a, // LCD85 --- Pin:9 LCDnAddress=55
+ CHAR3b, // LCD86 --- Pin:10 LCDnAddress=56
+ CHAR4a, // LCD87 --- Pin:11 LCDnAddress=57
+ CHAR4b, // LCD88 --- Pin:12 LCDnAddress=58
+ CHARCOM0, // LCD77 --- Pin:1 LCDnAddress=4D
+ CHARCOM1, // LCD78 --- Pin:2 LCDnAddress=4E
+ CHARCOM2, // LCD79 --- Pin:3 LCDnAddress=4F
+ CHARCOM3, // LCD80 --- Pin:4 LCDnAddress=50
+};
+
+const char ASCII_TO_WF_CODIFICATION_TABLE [ ] =
+{
+
+ /*
+ segA
+ ________
+ | |
+ segF | | segB
+ | |
+ -segG--
+ | |
+ segE | | segC
+ |________|
+ segD
+ */
+
+( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 0, offset=0
+(!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = 1, offset=4
+( SEGD+ SEGE+!SEGF+ SEGG) , (!SEGC+ SEGB+ SEGA) ,//Char = 2, offset=8
+( SEGD+!SEGE+!SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 3, offset=12
+(!SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = 4, offset=16
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = 5, offset=20
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = 6, offset=24
+(!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 7, offset=28
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 8, offset=32
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 9, offset=36
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = :, offset=40
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = ;, offset=44
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = <, offset=48
+( SEGD+!SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = =, offset=52
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = >, offset=56
+(!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ?, offset=60
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = @, offset=64
+(!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = A, offset=68
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = B, offset=72
+( SEGD+ SEGE+ SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = C, offset=76
+( SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = D, offset=80
+( SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = E, offset=84
+(!SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = F, offset=88
+( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = G, offset=92
+(!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = H, offset=96
+(!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = I, offset=100
+( SEGD+ SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = J, offset=104
+(!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = K, offset=108
+( SEGD+ SEGE+ SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = L, offset=112
+(!SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = M, offset=116
+(!SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = N, offset=120
+( SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = O, offset=124
+(!SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+ SEGB+ SEGA) ,//Char = P, offset=128
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = Q, offset=132
+(!SEGD+ SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = R, offset=136
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = S, offset=140
+( SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = T, offset=144
+( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = U, offset=148
+( SEGD+ SEGE+!SEGF+!SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = V, offset=152
+( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = W, offset=156
+(!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = X, offset=160
+( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = Y, offset=164
+( SEGD+!SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = Z, offset=168
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = [, offset=172
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = \, offset=176
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ], offset=180
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ^, offset=184
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = _, offset=188
+( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = `, offset=192
+};
+
+SLCD::SLCD() {
+ init();
+ CharPosition = 0;
+}
+
+void SLCD::init(){
+ SIM->SCGC5 |= SIM_SCGC5_SLCD_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
+
+ // configure pins for LCD operation
+ PORTC->PCR[20] = 0x00000000; //VLL2
+ PORTC->PCR[21] = 0x00000000; //VLL1
+ PORTC->PCR[22] = 0x00000000; //VCAP2
+ PORTC->PCR[23] = 0x00000000; //VCAP1
+ // Enable IRCLK
+ MCG->C1 = MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK;
+ MCG->C2 &= ~MCG_C2_IRCS_MASK ; //0 32KHZ internal reference clock; 1= 4MHz irc
+ LCD->GCR = 0x0;
+ LCD->AR = 0x0;
+ // LCD configurartion
+ LCD->GCR = ( LCD_GCR_RVEN_MASK*_LCDRVEN
+ | LCD_GCR_RVTRIM(_LCDRVTRIM) //0-15
+ | LCD_GCR_CPSEL_MASK*_LCDCPSEL
+ | LCD_GCR_LADJ(_LCDLOADADJUST) //0-3
+ | LCD_GCR_VSUPPLY_MASK*_LCDSUPPLY //0-1
+ |!LCD_GCR_FDCIEN_MASK
+ | LCD_GCR_ALTDIV(_LCDALTDIV) //0-3
+ |!LCD_GCR_LCDDOZE_MASK
+ |!LCD_GCR_LCDSTP_MASK
+ |!LCD_GCR_LCDEN_MASK //WILL BE ENABLE ON SUBSEQUENT STEP
+ | LCD_GCR_SOURCE_MASK*_LCDCLKSOURCE
+ | LCD_GCR_ALTSOURCE_MASK*_LCDALRCLKSOURCE
+ | LCD_GCR_LCLK(_LCDLCK) //0-7
+ | LCD_GCR_DUTY(_LCDDUTY) //0-7
+ );
+ uint8_t i;
+ uint32_t *p_pen;
+ uint8_t pen_offset; // 0 or 1
+ uint8_t pen_bit; // 0 to 31
+ LCD->PEN[0] = 0x0;
+ LCD->PEN[1] = 0x0;
+ LCD->BPEN[0] = 0x0;
+ LCD->BPEN[1] = 0x0;
+ p_pen = (uint32_t *)&LCD->PEN[0];
+ for (i=0;i<_LCDUSEDPINS;i++)
+ {
+ pen_offset = WF_ORDERING_TABLE[i]/32;
+ pen_bit = WF_ORDERING_TABLE[i]%32;
+ p_pen[pen_offset] |= 1 << pen_bit;
+ if (i>= _LCDFRONTPLANES) // Pin is a backplane
+ {
+ p_pen[pen_offset+2] |= 1 << pen_bit; // Enable BPEN
+ LCD->WF8B[(uint8_t)WF_ORDERING_TABLE[i]] = 1 << (i - _LCDFRONTPLANES); // fill with 0x01, 0x02, etc
+ }
+ }
+ LCD->GCR |= LCD_GCR_LCDEN_MASK;
+}
+
+int SLCD::_putc(int c) {
+ Write_Char(c);
+ return 0;
+}
+
+void SLCD::Write_Char (char lbValue) {
+ uint8_t char_val;
+ uint8_t temp;
+ uint8_t *lbpLCDWF;
+ uint8_t lbCounter;
+ uint16_t arrayOffset;
+ uint8_t position;
+
+ if (CharPosition >= _CHARNUM)
+ CharPosition = 0;
+ lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
+ /* only ascii character if value not writeable write as @ */
+ if (lbValue>='a' && lbValue<='z') {
+ lbValue -= 32; // UpperCase
+ }
+ if (lbValue<ASCCI_TABLE_START || lbValue >ASCCI_TABLE_END) {
+ lbValue = BLANK_CHARACTER; // default value as space
+ }
+ lbValue -=ASCCI_TABLE_START; // Remove the offset to search in the ascci table
+ arrayOffset = (lbValue * _CHAR_SIZE); // Compensate matrix offset
+ // ensure bLCD position is in valid limit
+ lbCounter = 0; //number of writings to complete one char
+ while (lbCounter<_CHAR_SIZE) {
+ position = (CharPosition) *_LCDTYPE + lbCounter;
+ temp=0;
+ if (lbCounter==1) {
+ temp = lbpLCDWF[WF_ORDERING_TABLE[position]] & 0x01;//bit 0 has the special symbol information
+ }
+ char_val = ASCII_TO_WF_CODIFICATION_TABLE[arrayOffset + lbCounter];
+ lbpLCDWF[WF_ORDERING_TABLE[position]] = char_val | temp;
+ // if (char_val==0) lbCounter = _CHAR_SIZE; //end of this character
+ lbCounter++;
+ }
+ CharPosition++;
+}
+
+void SLCD::Home (void)
+ {
+ CharPosition = 0;
+ }
+
+void SLCD::Contrast (uint8_t lbContrast)
+{
+ lbContrast &= 0x0F; //Forced to the only values accepted
+ LCD->GCR |= LCD_GCR_RVTRIM(lbContrast);
+}
+
+void SLCD::All_Segments (int mode)
+{
+ uint8_t lbTotalBytes = _CHARNUM * _LCDTYPE;
+ uint8_t lbCounter=0;
+ uint8_t *lbpLCDWF;
+
+ lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
+ while (lbCounter < lbTotalBytes)
+ {
+ if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[lbCounter++]]=_ALLON;}
+ else {lbpLCDWF[WF_ORDERING_TABLE[lbCounter++]]=0;}
+ }
+}
+
+void SLCD::DP1 (int mode)
+{
+ uint8_t *lbpLCDWF;
+ lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
+ if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[1]]|=1;}
+ else {lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[1]]&=~1;}
+}
+
+void SLCD::DP2 (int mode)
+{
+ uint8_t *lbpLCDWF;
+ lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
+ if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[3]]|=1;}
+ else {lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[3]]&=~1;}
+}
+
+void SLCD::DP3 (int mode)
+{
+ uint8_t *lbpLCDWF;
+ lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
+ if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[5]]|=1;}
+ else {lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[5]]&=~1;}
+}
+
+void SLCD::Colon (int mode)
+{
+ uint8_t *lbpLCDWF;
+ lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
+ if (mode==1){lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[7]]|=1;}
+ else {lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[7]]&=~1;}
+}
+
+
diff -r 01c4d4d8febf -r acdf490d94a7 SLCD/SLCD.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLCD/SLCD.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,44 @@
+#include "mbed.h"
+
+
+/* ------ sample usage------
+
+ #include "mbed.h"
+ #include "SLCD.h"
+
+ SLCD slcd;
+
+ main()
+ {
+ slcd.printf("1234"); // standard printf function, only charaters in ASCII_TO_WF_CODIFICATION_TABLE will display
+ slcd.putc("A"); // prints a single character
+ slcd.Write_Char('A'); // prints a single character
+ slcd.All_Segments(y); // y=1 for ALL segments on, 0 for ALL segments off
+ slcd.DPx(y); // x=DP1 to DP3, y=1 for on 0 for off
+ slcd.Colon(y); // y=1 for on, 0 for off
+ slcd.CharPosition=x; // x=0 to 3, 0 is start position
+ slcd.Home(); // sets next charater to posistion 0 (start)
+ slcd.Contrast (x); // set contrast x=0 - 15, 0 lightest, 15 darkest
+ }
+*/
+
+class SLCD : public Stream {
+ public:
+ SLCD();
+
+ void init();
+ void Write_Char(char lbValue);
+ void Home (void);
+ void Contrast (uint8_t lbContrast);
+ void All_Segments (int);
+ void DP1 (int);
+ void DP2 (int);
+ void DP3 (int);
+ void Colon (int);
+ uint8_t CharPosition;
+
+ virtual int _putc(int c);
+ virtual int _getc() {
+ return 0;
+ }
+};
diff -r 01c4d4d8febf -r acdf490d94a7 TSI.lib
--- a/TSI.lib Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/vsluiter/code/TSI/#4dc2f5a3a731
diff -r 01c4d4d8febf -r acdf490d94a7 TSI/TSISensor.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TSI/TSISensor.cpp Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,254 @@
+/* Freescale Semiconductor Inc.
+ * (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
+ * (c) Copyright 2001-2004 Motorola, Inc.
+ *
+ * mbed Microcontroller Library
+ * (c) Copyright 2009-2012 ARM Limited.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mbed.h"
+#include "TSISensor.h"
+
+#define NO_TOUCH 0
+#define SLIDER_LENGTH 40 //LENGTH in mm
+#define TOTAL_ELECTRODE 3
+
+#define TSI0a 0
+#define TSI1 1
+#define TSI2 2
+#define TSI3 3
+#define TSI4 4
+#define TSI5 5
+#define TSI6 6
+#define TSI7 7
+#define TSI8 8
+#define TSI9 9
+#define TSI10 10
+#define TSI11 11
+#define TSI12 12
+#define TSI13 13
+#define TSI14 14
+#define TSI15 15
+
+/*Chose the correct TSI channel for the electrode number*/
+#define ELECTRODE0 TSI9
+#define ELECTRODE1 TSI10
+#define ELECTRODE2 TSI0a
+#define ELECTRODE3 TSI1
+#define ELECTRODE4 TSI2
+#define ELECTRODE5 TSI3
+#define ELECTRODE6 TSI4
+#define ELECTRODE7 TSI5
+#define ELECTRODE8 TSI6
+#define ELECTRODE9 TSI7
+#define ELECTRODE10 TSI8
+#define ELECTRODE11 TSI11
+#define ELECTRODE12 TSI12
+#define ELECTRODE13 TSI13
+#define ELECTRODE14 TSI14
+#define ELECTRODE15 TSI15
+
+#define THRESHOLD0 100
+#define THRESHOLD1 100
+#define THRESHOLD2 100
+#define THRESHOLD3 100
+#define THRESHOLD4 100
+#define THRESHOLD5 100
+#define THRESHOLD6 100
+#define THRESHOLD7 100
+#define THRESHOLD8 100
+#define THRESHOLD9 100
+#define THRESHOLD10 100
+#define THRESHOLD11 100
+#define THRESHOLD12 100
+#define THRESHOLD13 100
+#define THRESHOLD14 100
+#define THRESHOLD15 100
+
+static uint8_t total_electrode = TOTAL_ELECTRODE;
+static uint8_t elec_array[16]={ELECTRODE0,ELECTRODE1,ELECTRODE2,ELECTRODE3,ELECTRODE4,ELECTRODE5,
+ ELECTRODE6,ELECTRODE7,ELECTRODE8,ELECTRODE9,ELECTRODE10,ELECTRODE11,
+ ELECTRODE12,ELECTRODE13,ELECTRODE14,ELECTRODE15};
+static uint16_t gu16TSICount[16];
+static uint16_t gu16Baseline[16];
+static uint16_t gu16Threshold[16]={THRESHOLD0,THRESHOLD1,THRESHOLD2,THRESHOLD3,THRESHOLD4,THRESHOLD5,
+ THRESHOLD6,THRESHOLD7,THRESHOLD8,THRESHOLD9,THRESHOLD10,THRESHOLD11,
+ THRESHOLD12,THRESHOLD13,THRESHOLD14,THRESHOLD15};
+static uint16_t gu16Delta[16];
+static uint8_t ongoing_elec;
+static uint8_t end_flag = 1;
+
+static uint8_t SliderPercentegePosition[2] = {NO_TOUCH,NO_TOUCH};
+static uint8_t SliderDistancePosition[2] = {NO_TOUCH,NO_TOUCH};
+static uint32_t AbsolutePercentegePosition = NO_TOUCH;
+static uint32_t AbsoluteDistancePosition = NO_TOUCH;
+
+static void tsi_irq();
+
+TSISensor::TSISensor() {
+ SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
+ SIM->SCGC5 |= SIM_SCGC5_TSI_MASK;
+
+ TSI0->GENCS |= (TSI_GENCS_ESOR_MASK
+ | TSI_GENCS_MODE(0)
+ | TSI_GENCS_REFCHRG(4)
+ | TSI_GENCS_DVOLT(0)
+ | TSI_GENCS_EXTCHRG(7)
+ | TSI_GENCS_PS(4)
+ | TSI_GENCS_NSCN(11)
+ | TSI_GENCS_TSIIEN_MASK
+ | TSI_GENCS_STPE_MASK
+ );
+
+ TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;
+
+ NVIC_SetVector(TSI0_IRQn, (uint32_t)&tsi_irq);
+ NVIC_EnableIRQ(TSI0_IRQn);
+
+ selfCalibration();
+}
+
+void TSISensor::TSISensor_reset(void) {
+ SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
+ SIM->SCGC5 |= SIM_SCGC5_TSI_MASK;
+
+ TSI0->GENCS |= (TSI_GENCS_ESOR_MASK
+ | TSI_GENCS_MODE(0)
+ | TSI_GENCS_REFCHRG(4)
+ | TSI_GENCS_DVOLT(0)
+ | TSI_GENCS_EXTCHRG(7)
+ | TSI_GENCS_PS(4)
+ | TSI_GENCS_NSCN(11)
+ | TSI_GENCS_TSIIEN_MASK
+ | TSI_GENCS_STPE_MASK
+ );
+
+ TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;
+
+ //NVIC_SetVector(TSI0_IRQn, (uint32_t)&tsi_irq);
+ //NVIC_EnableIRQ(TSI0_IRQn);
+
+ selfCalibration();
+}
+
+void TSISensor::selfCalibration(void)
+{
+ unsigned char cnt;
+ unsigned char trigger_backup;
+
+ TSI0->GENCS |= TSI_GENCS_EOSF_MASK; // Clear End of Scan Flag
+ TSI0->GENCS &= ~TSI_GENCS_TSIEN_MASK; // Disable TSI module
+
+ if(TSI0->GENCS & TSI_GENCS_STM_MASK) // Back-up TSI Trigger mode from Application
+ trigger_backup = 1;
+ else
+ trigger_backup = 0;
+
+ TSI0->GENCS &= ~TSI_GENCS_STM_MASK; // Use SW trigger
+ TSI0->GENCS &= ~TSI_GENCS_TSIIEN_MASK; // Enable TSI interrupts
+
+ TSI0->GENCS |= TSI_GENCS_TSIEN_MASK; // Enable TSI module
+
+ for(cnt=0; cnt < total_electrode; cnt++) // Get Counts when Electrode not pressed
+ {
+ TSI0->DATA = ((elec_array[cnt] << TSI_DATA_TSICH_SHIFT) );
+ TSI0->DATA |= TSI_DATA_SWTS_MASK;
+ while(!(TSI0->GENCS & TSI_GENCS_EOSF_MASK));
+ TSI0->GENCS |= TSI_GENCS_EOSF_MASK;
+ gu16Baseline[cnt] = (TSI0->DATA & TSI_DATA_TSICNT_MASK);
+ }
+
+ TSI0->GENCS &= ~TSI_GENCS_TSIEN_MASK; // Disable TSI module
+ TSI0->GENCS |= TSI_GENCS_TSIIEN_MASK; // Enale TSI interrupt
+ if(trigger_backup) // Restore trigger mode
+ TSI0->GENCS |= TSI_GENCS_STM_MASK;
+ else
+ TSI0->GENCS &= ~TSI_GENCS_STM_MASK;
+
+ TSI0->GENCS |= TSI_GENCS_TSIEN_MASK; // Enable TSI module
+
+ TSI0->DATA = ((elec_array[0]<<TSI_DATA_TSICH_SHIFT) );
+ TSI0->DATA |= TSI_DATA_SWTS_MASK;
+}
+
+void TSISensor::sliderRead(void ) {
+ if(end_flag) {
+ end_flag = 0;
+ if((gu16Delta[0] > gu16Threshold[0])||(gu16Delta[1] > gu16Threshold[1])) {
+ SliderPercentegePosition[0] = (gu16Delta[0]*100)/(gu16Delta[0]+gu16Delta[1]);
+ SliderPercentegePosition[1] = (gu16Delta[1]*100)/(gu16Delta[0]+gu16Delta[1]);
+ SliderDistancePosition[0] = (SliderPercentegePosition[0]* SLIDER_LENGTH)/100;
+ SliderDistancePosition[1] = (SliderPercentegePosition[1]* SLIDER_LENGTH)/100;
+ AbsolutePercentegePosition = ((100 - SliderPercentegePosition[0]) + SliderPercentegePosition[1])/2;
+ AbsoluteDistancePosition = ((SLIDER_LENGTH - SliderDistancePosition[0]) + SliderDistancePosition[1])/2;
+ } else {
+ SliderPercentegePosition[0] = NO_TOUCH;
+ SliderPercentegePosition[1] = NO_TOUCH;
+ SliderDistancePosition[0] = NO_TOUCH;
+ SliderDistancePosition[1] = NO_TOUCH;
+ AbsolutePercentegePosition = NO_TOUCH;
+ AbsoluteDistancePosition = NO_TOUCH;
+ }
+ }
+}
+
+float TSISensor::readPercentage() {
+ sliderRead();
+ return (float)AbsolutePercentegePosition/100.0;
+}
+
+uint8_t TSISensor::readDistance() {
+ sliderRead();
+ return AbsoluteDistancePosition;
+}
+
+uint16_t TSISensor::readValue(uint8_t index)
+{
+ return gu16TSICount[index];
+}
+
+static void changeElectrode(void)
+{
+ int16_t u16temp_delta;
+
+ gu16TSICount[ongoing_elec] = (TSI0->DATA & TSI_DATA_TSICNT_MASK); // Save Counts for current electrode
+ u16temp_delta = gu16TSICount[ongoing_elec] - gu16Baseline[ongoing_elec]; // Obtains Counts Delta from callibration reference
+ if(u16temp_delta < 0)
+ gu16Delta[ongoing_elec] = 0;
+ else
+ gu16Delta[ongoing_elec] = u16temp_delta;
+
+ //Change Electrode to Scan
+ if(total_electrode > 1)
+ {
+ if((total_electrode-1) > ongoing_elec)
+ ongoing_elec++;
+ else
+ ongoing_elec = 0;
+
+ TSI0->DATA = ((elec_array[ongoing_elec]<<TSI_DATA_TSICH_SHIFT) );
+ TSI0->DATA |= TSI_DATA_SWTS_MASK;
+ }
+}
+
+void tsi_irq(void)
+{
+ end_flag = 1;
+ TSI0->GENCS |= TSI_GENCS_EOSF_MASK; // Clear End of Scan Flag
+ changeElectrode();
+}
diff -r 01c4d4d8febf -r acdf490d94a7 TSI/TSISensor.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TSI/TSISensor.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,73 @@
+/* Freescale Semiconductor Inc.
+ * (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
+ * (c) Copyright 2001-2004 Motorola, Inc.
+ *
+ * mbed Microcontroller Library
+ * (c) Copyright 2009-2012 ARM Limited.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef TSISENSOR_H
+#define TSISENSOR_H
+
+/**
+* TSISensor example
+*
+* @code
+* #include "mbed.h"
+* #include "TSISensor.h"
+*
+* int main(void) {
+* PwmOut led(LED_GREEN);
+* TSISensor tsi;
+*
+* while (true) {
+* led = 1.0 - tsi.readPercentage();
+* wait(0.1);
+* }
+* }
+* @endcode
+*/
+class TSISensor {
+public:
+ /**
+ * Initialize the TSI Touch Sensor
+ */
+ TSISensor();
+
+ /**
+ * Read Touch Sensor percentage value
+ *
+ * @returns percentage value between [0 ... 1]
+ */
+ float readPercentage();
+
+ /**
+ * Read Touch Sensor distance
+ *
+ * @returns distance in mm. The value is between [0 ... 40]
+ */
+ uint8_t readDistance();
+ uint16_t readValue(uint8_t);
+ void TSISensor_reset(void);
+
+private:
+ void sliderRead(void);
+ void selfCalibration(void);
+};
+
+#endif
diff -r 01c4d4d8febf -r acdf490d94a7 mbed-src.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-src.lib Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-src/#8435094ec241
diff -r 01c4d4d8febf -r acdf490d94a7 mbed.bld
--- a/mbed.bld Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/7d30d6019079
\ No newline at end of file
diff -r 01c4d4d8febf -r acdf490d94a7 pt.lib
--- a/pt.lib Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-pt#738c912b9ca3
diff -r 01c4d4d8febf -r acdf490d94a7 pt/graham-pt.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/graham-pt.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,493 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: graham-pt.h,v 1.1 2005/10/04 08:30:05 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+struct pt {
+ lc_t lc;
+};
+
+/**
+ * Extended PT.
+ * This add's a flags field to the basic pt structure.
+ */
+struct ptx {
+ lc_t lc;
+ unsigned short flags;
+};
+
+#define PT_THREAD_WAITING 0
+#define PT_THREAD_EXITED 1
+
+/** Extended PT flag : thread is sleeping */
+#define PT_F_SLEEPING 1
+/** Extended PT flag : thread has been flagged to be killed (will exit on next block/wait/yield) */
+#define PT_F_KILL 2
+/** Extended PT flag : thread is waiting */
+#define PT_F_WAITING 4
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * Example:
+ \code
+ PT_THREAD(consumer(struct pt *p, int event)) {
+ PT_BEGIN(p);
+ while(1) {
+ PT_WAIT_UNTIL(p, event == AVAILABLE);
+ consume();
+ PT_WAIT_UNTIL(p, event == CONSUMED);
+ acknowledge_consumed();
+ }
+ PT_END(p);
+ }
+ \endcode
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * Example:
+ *
+ \code
+ void main(void) {
+ struct pt p;
+ int event;
+
+ PT_INIT(&p);
+ while(PT_SCHEDULE(consumer(&p, event))) {
+ event = get_event();
+ }
+ }
+ \endcode
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt) LC_INIT((pt)->lc)
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * Example:
+ *
+ \code
+ PT_THREAD(producer(struct pt *p, int event)) {
+ PT_BEGIN(p);
+ while(1) {
+ PT_WAIT_UNTIL(p, event == CONSUMED || event == DROPPED);
+ produce();
+ PT_WAIT_UNTIL(p, event == PRODUCED);
+ }
+
+ PT_END(p);
+ }
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) LC_RESUME((pt)->lc)
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * Example:
+ \code
+ PT_THREAD(seconds(struct pt *p)) {
+ PT_BEGIN(p);
+
+ PT_WAIT_UNTIL(p, time >= 2 * SECOND);
+ printf("Two seconds have passed\n");
+
+ PT_END(p);
+ }
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition) \
+ do { \
+ LC_SET((pt)->lc); \
+ if(sizeof(*(pt))==sizeof(struct ptx)) \
+ { \
+ if(((struct ptx*)(pt))->flags&PT_F_KILL) \
+ { \
+ PT_INIT(pt); \
+ return PT_THREAD_EXITED; \
+ } \
+ if(condition) \
+ ((struct ptx*)(pt))->flags&=PT_F_WAITING; \
+ else \
+ ((struct ptx*)(pt))->flags|=PT_F_WAITING; \
+ if(((struct ptx*)(pt))->flags&PT_F_WAITING) { \
+ return PT_THREAD_WAITING; \
+ } \
+ }else{ \
+ if(!(condition)) { \
+ return PT_THREAD_WAITING; \
+ } \
+ } \
+ } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
+
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * Example:
+ \code
+ PT_THREAD(child(struct pt *p, int event)) {
+ PT_BEGIN(p);
+
+ PT_WAIT_UNTIL(p, event == EVENT1);
+
+ PT_END(p);
+ }
+
+ PT_THREAD(parent(struct pt *p, struct pt *child_pt, int event)) {
+ PT_BEGIN(p);
+
+ PT_INIT(child_pt);
+
+ PT_WAIT_THREAD(p, child(child_pt, event));
+
+ PT_END(p);
+ }
+ \endcode
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * Example:
+ \code
+ static struct pt parent_pt, child_pt;
+ int should_spawn_flag;
+
+ PT_THREAD(child(struct pt *pt)) {
+ PT_BEGIN(pt);
+
+ while(all_items_processed()) {
+ process_item();
+ PT_WAIT_UNTIL(pt, item_processed());
+ }
+
+ PT_END(pt);
+ }
+
+ PT_THREAD(parent(void)) {
+ PT_BEGIN(&parent_pt);
+
+ if(should_spawn_flag) {
+ PT_SPAWN(&parent_pt, &child_pt, child(&child_pt));
+ }
+
+ PT_END(&parent_pt);
+ }
+ \endcode
+ *
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread) \
+ do { \
+ PT_INIT((child)); \
+ PT_WAIT_THREAD((pt), (thread)); \
+ } while(0)
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt) \
+ do { \
+ PT_INIT(pt); \
+ return PT_THREAD_WAITING; \
+ } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt) \
+ do { \
+ PT_INIT(pt); \
+ return PT_THREAD_EXITED; \
+ } while(0)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It should
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_EXIT(pt)
+
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * Example
+ \code
+ void main(void) {
+ struct pt p;
+ int event;
+
+ PT_INIT(&p);
+ while(PT_SCHEDULE(consumer(&p, event))) {
+ event = get_event();
+ }
+ }
+ \endcode
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) (f == PT_THREAD_WAITING)
+
+/**
+ * Declarare that a protothread can yield.
+ *
+ * If a protothread should be able to yield with the PT_YIELD()
+ * statement, this flag must be placed first in the protothread's
+ * function body.
+ *
+ * Example:
+ \code
+ static
+ PT_THREAD(loop_thread(struct pt *pt))
+ {
+ PT_YIELDING();
+ static int i;
+
+ PT_BEGIN(pt);
+
+ for(i = 0; i < 200; ++i) {
+ handle_item(i);
+ PT_YIELD(pt);
+ }
+
+ PT_END(pt);
+ }
+ \endcode
+ *
+ * \hideinitializer
+ */
+#define PT_YIELDING() char pt_yielded = 1
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \note The PT_YIELDING() flag must be placed first in the
+ * protothread's body if the PT_YIELD() function should be used.
+ *
+ * Example
+ \code
+static
+PT_THREAD(fade(struct pt *pt))
+{
+ PT_YIELDING();
+ static int delay;
+
+ PT_BEGIN(pt);
+
+ for(delay = 3980; delay > 20; delay -= 20) {
+ leds_red(LEDS_ON);
+ clock_delay(4000 - delay);
+ leds_red(LEDS_OFF);
+ clock_delay(delay);
+ PT_YIELD(pt);
+ }
+
+ PT_END(pt);
+}
+ \endcode
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt) \
+ do { \
+ pt_yielded = 0; \
+ PT_WAIT_UNTIL(pt, pt_yielded); \
+ } while(0)
+
+/*
+ * Extended Protothread API.
+ * The following functions require a struct ptx, rather than a plan struct pt.
+ */
+
+/**
+ * Put a protothread to sleep.
+ * Execution of the thread won't continue until another thread explicitly wakes the thread
+ * with PT_WAKE().
+ * Requires a ptx.
+ */
+#define PT_SLEEP(ptx) \
+ do { \
+ ptx->flags|=PT_F_SLEEPING; \
+ PT_WAIT_UNTIL(ptx, (((ptx)->flags&PT_F_SLEEPING)==0)); \
+ } while(0)
+
+/**
+ * Wake a protothread.
+ * Wake up a protothread if it is sleeping (ie. has called PT_SLEEP()) - if the thread isn't sleeping,
+ * then it has no effect.
+ * NOTE: Requires a ptx.
+ */
+#define PT_WAKE(ptx) (ptx)->flags&=~PT_F_SLEEPING
+
+/**
+ * Kill a protothread.
+ * The thread is marked with the kill flag and will exit next time the thread sleeps/waits/yields.
+ * NOTE: Requires a ptx.
+ */
+#define PT_KILL(ptx) (ptx)->flags&=~PT_F_KILL
+
+/**
+ * Is a protothread blocked?
+ * Returns non-zero is the thread is waiting.
+ * NOTE: Requires a ptx.
+ */
+#define PT_ISBLOCKED(ptx) ((ptx)->flags&PT_F_WAITING)
+
+#endif /* __PT_H__ */
+
+
+/** @} */
diff -r 01c4d4d8febf -r acdf490d94a7 pt/lc-addrlabels.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/lc-addrlabels.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-addrlabels.h,v 1.4 2006/06/03 11:29:43 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on the "Labels as
+ * values" feature of gcc
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations is based on a special
+ * feature of the GCC C compiler called "labels as values". This
+ * feature allows assigning pointers with the address of the code
+ * corresponding to a particular C label.
+ *
+ * For more information, see the GCC documentation:
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+ *
+ */
+
+#ifndef __LC_ADDRLABELS_H__
+#define __LC_ADDRLABELS_H__
+
+/** \hideinitializer */
+typedef void * lc_t;
+
+#define LC_INIT(s) s = NULL
+
+#define LC_RESUME(s) \
+ do { \
+ if(s != NULL) { \
+ goto *s; \
+ } \
+ } while(0)
+
+#define LC_CONCAT2(s1, s2) s1##s2
+#define LC_CONCAT(s1, s2) LC_CONCAT2(s1, s2)
+
+#define LC_SET(s) \
+ do { \
+ LC_CONCAT(LC_LABEL, __LINE__): \
+ (s) = &&LC_CONCAT(LC_LABEL, __LINE__); \
+ } while(0)
+
+#define LC_END(s)
+
+#endif /* __LC_ADDRLABELS_H__ */
+/** @} */
diff -r 01c4d4d8febf -r acdf490d94a7 pt/lc-switch.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/lc-switch.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-switch.h,v 1.4 2006/06/03 11:29:43 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on switch() statment
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations uses the C switch()
+ * statement to resume execution of a function somewhere inside the
+ * function's body. The implementation is based on the fact that
+ * switch() statements are able to jump directly into the bodies of
+ * control structures such as if() or while() statmenets.
+ *
+ * This implementation borrows heavily from Simon Tatham's coroutines
+ * implementation in C:
+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ */
+
+#ifndef __LC_SWITCH_H__
+#define __LC_SWITCH_H__
+
+/* WARNING! lc implementation using switch() does not work if an
+ LC_SET() is done within another switch() statement! */
+
+/** \hideinitializer */
+typedef unsigned short lc_t;
+
+#define LC_INIT(s) s = 0;
+
+#define LC_RESUME(s) switch(s) { case 0:
+
+#define LC_SET(s) s = __LINE__; case __LINE__:
+
+#define LC_END(s) }
+
+#endif /* __LC_SWITCH_H__ */
+
+/** @} */
diff -r 01c4d4d8febf -r acdf490d94a7 pt/lc.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/lc.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 file is part of the protothreads library.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc.h,v 1.2 2005/02/24 10:36:59 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup lc Local continuations
+ * @{
+ *
+ * Local continuations form the basis for implementing protothreads. A
+ * local continuation can be <i>set</i> in a specific function to
+ * capture the state of the function. After a local continuation has
+ * been set can be <i>resumed</i> in order to restore the state of the
+ * function at the point where the local continuation was set.
+ *
+ *
+ */
+
+/**
+ * \file lc.h
+ * Local continuations
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifdef DOXYGEN
+/**
+ * Initialize a local continuation.
+ *
+ * This operation initializes the local continuation, thereby
+ * unsetting any previously set continuation state.
+ *
+ * \hideinitializer
+ */
+#define LC_INIT(lc)
+
+/**
+ * Set a local continuation.
+ *
+ * The set operation saves the state of the function at the point
+ * where the operation is executed. As far as the set operation is
+ * concerned, the state of the function does <b>not</b> include the
+ * call-stack or local (automatic) variables, but only the program
+ * counter and such CPU registers that needs to be saved.
+ *
+ * \hideinitializer
+ */
+#define LC_SET(lc)
+
+/**
+ * Resume a local continuation.
+ *
+ * The resume operation resumes a previously set local continuation, thus
+ * restoring the state in which the function was when the local
+ * continuation was set. If the local continuation has not been
+ * previously set, the resume operation does nothing.
+ *
+ * \hideinitializer
+ */
+#define LC_RESUME(lc)
+
+/**
+ * Mark the end of local continuation usage.
+ *
+ * The end operation signifies that local continuations should not be
+ * used any more in the function. This operation is not needed for
+ * most implementations of local continuation, but is required by a
+ * few implementations.
+ *
+ * \hideinitializer
+ */
+#define LC_END(lc)
+
+/**
+ * \var typedef lc_t;
+ *
+ * The local continuation type.
+ *
+ * \hideinitializer
+ */
+#endif /* DOXYGEN */
+
+#ifndef __LC_H__
+#define __LC_H__
+
+
+#ifdef LC_INCLUDE
+#include LC_INCLUDE
+#else
+#include "lc-switch.h"
+#endif /* LC_INCLUDE */
+
+#endif /* __LC_H__ */
+
+/** @} */
+/** @} */
diff -r 01c4d4d8febf -r acdf490d94a7 pt/pt-sem.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/pt-sem.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 file is part of the protothreads library.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt-sem.h,v 1.2 2005/02/24 10:36:59 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup ptsem Protothread semaphores
+ * @{
+ *
+ * This module implements counting semaphores on top of
+ * protothreads. Semaphores are a synchronization primitive that
+ * provide two operations: "wait" and "signal". The "wait" operation
+ * checks the semaphore counter and blocks the thread if the counter
+ * is zero. The "signal" operation increases the semaphore counter but
+ * does not block. If another thread has blocked waiting for the
+ * semaphore that is signalled, the blocked thread will become
+ * runnable again.
+ *
+ * Semaphores can be used to implement other, more structured,
+ * synchronization primitives such as monitors and message
+ * queues/bounded buffers (see below).
+ *
+ * The following example shows how the producer-consumer problem, also
+ * known as the bounded buffer problem, can be solved using
+ * protothreads and semaphores. Notes on the program follow after the
+ * example.
+ *
+ \code
+#include "pt-sem.h"
+
+#define NUM_ITEMS 32
+#define BUFSIZE 8
+
+static struct pt_sem mutex, full, empty;
+
+PT_THREAD(producer(struct pt *pt))
+{
+ static int produced;
+
+ PT_BEGIN(pt);
+
+ for(produced = 0; produced < NUM_ITEMS; ++produced) {
+
+ PT_SEM_WAIT(pt, &full);
+
+ PT_SEM_WAIT(pt, &mutex);
+ add_to_buffer(produce_item());
+ PT_SEM_SIGNAL(pt, &mutex);
+
+ PT_SEM_SIGNAL(pt, &empty);
+ }
+
+ PT_END(pt);
+}
+
+PT_THREAD(consumer(struct pt *pt))
+{
+ static int consumed;
+
+ PT_BEGIN(pt);
+
+ for(consumed = 0; consumed < NUM_ITEMS; ++consumed) {
+
+ PT_SEM_WAIT(pt, &empty);
+
+ PT_SEM_WAIT(pt, &mutex);
+ consume_item(get_from_buffer());
+ PT_SEM_SIGNAL(pt, &mutex);
+
+ PT_SEM_SIGNAL(pt, &full);
+ }
+
+ PT_END(pt);
+}
+
+PT_THREAD(driver_thread(struct pt *pt))
+{
+ static struct pt pt_producer, pt_consumer;
+
+ PT_BEGIN(pt);
+
+ PT_SEM_INIT(&empty, 0);
+ PT_SEM_INIT(&full, BUFSIZE);
+ PT_SEM_INIT(&mutex, 1);
+
+ PT_INIT(&pt_producer);
+ PT_INIT(&pt_consumer);
+
+ PT_WAIT_THREAD(pt, producer(&pt_producer) &
+ consumer(&pt_consumer));
+
+ PT_END(pt);
+}
+ \endcode
+ *
+ * The program uses three protothreads: one protothread that
+ * implements the consumer, one thread that implements the producer,
+ * and one protothread that drives the two other protothreads. The
+ * program uses three semaphores: "full", "empty" and "mutex". The
+ * "mutex" semaphore is used to provide mutual exclusion for the
+ * buffer, the "empty" semaphore is used to block the consumer is the
+ * buffer is empty, and the "full" semaphore is used to block the
+ * producer is the buffer is full.
+ *
+ * The "driver_thread" holds two protothread state variables,
+ * "pt_producer" and "pt_consumer". It is important to note that both
+ * these variables are declared as <i>static</i>. If the static
+ * keyword is not used, both variables are stored on the stack. Since
+ * protothreads do not store the stack, these variables may be
+ * overwritten during a protothread wait operation. Similarly, both
+ * the "consumer" and "producer" protothreads declare their local
+ * variables as static, to avoid them being stored on the stack.
+ *
+ *
+ */
+
+/**
+ * \file
+ * Couting semaphores implemented on protothreads
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_SEM_H__
+#define __PT_SEM_H__
+
+#include "pt.h"
+
+struct pt_sem {
+ unsigned int count;
+};
+
+/**
+ * Initialize a semaphore
+ *
+ * This macro initializes a semaphore with a value for the
+ * counter. Internally, the semaphores use an "unsigned int" to
+ * represent the counter, and therefore the "count" argument should be
+ * within range of an unsigned int.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \param c (unsigned int) The initial count of the semaphore.
+ * \hideinitializer
+ */
+#define PT_SEM_INIT(s, c) (s)->count = c
+
+/**
+ * Wait for a semaphore
+ *
+ * This macro carries out the "wait" operation on the semaphore. The
+ * wait operation causes the protothread to block while the counter is
+ * zero. When the counter reaches a value larger than zero, the
+ * protothread will continue.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_WAIT(pt, s) \
+ do { \
+ PT_WAIT_UNTIL(pt, (s)->count > 0); \
+ --(s)->count; \
+ } while(0)
+
+/**
+ * Signal a semaphore
+ *
+ * This macro carries out the "signal" operation on the semaphore. The
+ * signal operation increments the counter inside the semaphore, which
+ * eventually will cause waiting protothreads to continue executing.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_SIGNAL(pt, s) ++(s)->count
+
+#endif /* __PT_SEM_H__ */
+
+/** @} */
+/** @} */
+
diff -r 01c4d4d8febf -r acdf490d94a7 pt/pt.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pt/pt.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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 file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt.h,v 1.7 2006/10/02 07:52:56 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+struct pt {
+ lc_t lc;
+};
+
+#define PT_WAITING 0
+#define PT_YIELDED 1
+#define PT_EXITED 2
+#define PT_ENDED 3
+
+/**
+ * \name Initialization
+ * @{
+ */
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt) LC_INIT((pt)->lc)
+
+/** @} */
+
+/**
+ * \name Declaration and definition
+ * @{
+ */
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It must
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
+ PT_INIT(pt); return PT_ENDED; }
+
+/** @} */
+
+/**
+ * \name Blocked wait
+ * @{
+ */
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition) \
+ do { \
+ LC_SET((pt)->lc); \
+ if(!(condition)) { \
+ return PT_WAITING; \
+ } \
+ } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
+
+/** @} */
+
+/**
+ * \name Hierarchical protothreads
+ * @{
+ */
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread) \
+ do { \
+ PT_INIT((child)); \
+ PT_WAIT_THREAD((pt), (thread)); \
+ } while(0)
+
+/** @} */
+
+/**
+ * \name Exiting and restarting
+ * @{
+ */
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt) \
+ do { \
+ PT_INIT(pt); \
+ return PT_WAITING; \
+ } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt) \
+ do { \
+ PT_INIT(pt); \
+ return PT_EXITED; \
+ } while(0)
+
+/** @} */
+
+/**
+ * \name Calling a protothread
+ * @{
+ */
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) ((f) < PT_EXITED)
+
+/** @} */
+
+/**
+ * \name Yielding from a protothread
+ * @{
+ */
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt) \
+ do { \
+ PT_YIELD_FLAG = 0; \
+ LC_SET((pt)->lc); \
+ if(PT_YIELD_FLAG == 0) { \
+ return PT_YIELDED; \
+ } \
+ } while(0)
+
+/**
+ * \brief Yield from the protothread until a condition occurs.
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * This function will yield the protothread, until the
+ * specified condition evaluates to true.
+ *
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD_UNTIL(pt, cond) \
+ do { \
+ PT_YIELD_FLAG = 0; \
+ LC_SET((pt)->lc); \
+ if((PT_YIELD_FLAG == 0) || !(cond)) { \
+ return PT_YIELDED; \
+ } \
+ } while(0)
+
+/** @} */
+
+#endif /* __PT_H__ */
+
+/** @} */
diff -r 01c4d4d8febf -r acdf490d94a7 sens_itf.lib
--- a/sens_itf.lib Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/marcelobarrosalmeida/code/sens_itf/#d3dffda90b26
diff -r 01c4d4d8febf -r acdf490d94a7 sens_itf/sens_itf.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_itf.c Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,407 @@
+#include <string.h>
+#include <stdint.h>
+#include "sens_itf.h"
+#include "../util/buf_io.h"
+#include "../util/crc16.h"
+
+#define SENS_ITF_DBG_FRAME 1
+
+uint8_t sens_itf_unpack_point_value(sens_itf_cmd_point_t *point, uint8_t *buf)
+{
+ uint8_t size = 0;
+
+ switch (point->type)
+ {
+ case SENS_ITF_DT_U8:
+ point->value.u8 = buf_io_get8_fl(buf);
+ size = 1;
+ break;
+ case SENS_ITF_DT_S8:
+ point->value.s8 = buf_io_get8_fl(buf);
+ size = 1;
+ break;
+ case SENS_ITF_DT_U16:
+ point->value.u16 = buf_io_get16_fl(buf);
+ size = 2;
+ break;
+ case SENS_ITF_DT_S16:
+ point->value.s16 = buf_io_get16_fl(buf);
+ size = 2;
+ break;
+ case SENS_ITF_DT_U32:
+ point->value.u32 = buf_io_get32_fl(buf);
+ size = 4;
+ break;
+ case SENS_ITF_DT_S32:
+ point->value.s32 = buf_io_get32_fl(buf);
+ size = 4;
+ break;
+ case SENS_ITF_DT_U64:
+ point->value.u64 = buf_io_get64_fl(buf);
+ size = 8;
+ break;
+ case SENS_ITF_DT_S64:
+ point->value.s64 = buf_io_get64_fl(buf);
+ size = 8;
+ break;
+ case SENS_ITF_DT_FLOAT:
+ point->value.fp32 = buf_io_getf_fl(buf);
+ size = 4;
+ break;
+ case SENS_ITF_DT_DOUBLE:
+ point->value.fp64 = buf_io_getd_fl(buf);
+ size = 8;
+ break;
+ default:
+ break;
+ }
+
+ return size;
+}
+
+uint8_t sens_itf_pack_point_value(const sens_itf_cmd_point_t *point, uint8_t *buf)
+{
+ uint8_t size = 0;
+
+ switch (point->type)
+ {
+ case SENS_ITF_DT_U8:
+ buf_io_put8_tl(point->value.u8, buf);
+ size = 1;
+ break;
+ case SENS_ITF_DT_S8:
+ buf_io_put8_tl(point->value.s8, buf);
+ size = 1;
+ break;
+ case SENS_ITF_DT_U16:
+ buf_io_put16_tl(point->value.u16, buf);
+ size = 2;
+ break;
+ case SENS_ITF_DT_S16:
+ buf_io_put16_tl(point->value.s16, buf);
+ size = 2;
+ break;
+ case SENS_ITF_DT_U32:
+ buf_io_put32_tl(point->value.u32, buf);
+ size = 4;
+ break;
+ case SENS_ITF_DT_S32:
+ buf_io_put32_tl(point->value.s32, buf);
+ size = 4;
+ break;
+ case SENS_ITF_DT_U64:
+ buf_io_put64_tl(point->value.u64, buf);
+ size = 8;
+ break;
+ case SENS_ITF_DT_S64:
+ buf_io_put64_tl(point->value.s64, buf);
+ size = 8;
+ break;
+ case SENS_ITF_DT_FLOAT:
+ buf_io_putf_tl(point->value.fp32, buf);
+ size = 4;
+ break;
+ case SENS_ITF_DT_DOUBLE:
+ buf_io_putd_tl(point->value.fp64, buf);
+ size = 8;
+ break;
+ default:
+ break;
+ }
+
+ return size;
+}
+
+uint8_t sens_itf_unpack_cmd_req(sens_itf_cmd_req_t *cmd, uint8_t *frame, uint8_t frame_size)
+{
+ uint8_t *buf = frame;
+ uint16_t crc;
+ uint16_t frame_crc;
+ uint8_t size;
+
+ if (frame_size < 3)
+ {
+ //OS_UTIL_LOG(SENS_ITF_DBG_FRAME, ("Invalid frame size %d", frame_size));
+ return 0;
+ }
+
+ // minimal header decoding
+ cmd->hdr.size = buf_io_get8_fl_ap(buf);
+ cmd->hdr.addr = buf_io_get8_fl_ap(buf);
+
+ frame_crc = buf_io_get16_fl(&frame[cmd->hdr.size]);
+ crc = crc16_calc(frame, cmd->hdr.size);
+ cmd->crc = frame_crc;
+
+ if (frame_crc != crc)
+ {
+ //OS_UTIL_LOG(SENS_ITF_DBG_FRAME, ("Invalid CRC %04X <> %04X", frame_crc, crc));
+ return 0;
+ }
+
+ switch (cmd->hdr.addr)
+ {
+ case SENS_ITF_REGMAP_BRD_CMD:
+ cmd->payload.command_cmd.cmd = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_WRITE_BAT_STATUS:
+ cmd->payload.bat_status_cmd.status = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_WRITE_BAT_CHARGE:
+ cmd->payload.bat_charge_cmd.charge = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_DSP_WRITE:
+ cmd->payload.write_display_cmd.line = buf_io_get8_fl_ap(buf);
+ memcpy(cmd->payload.write_display_cmd.msg,buf,SENS_ITF_DSP_MSG_MAX_SIZE);
+ buf += SENS_ITF_DSP_MSG_MAX_SIZE;
+ break;
+ case SENS_ITF_REGMAP_WPAN_STATUS:
+ cmd->payload.wpan_status_cmd.status = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_WPAN_STRENGTH:
+ cmd->payload.wpan_strength_cmd.strenght = buf_io_get8_fl_ap(buf);
+ break;
+ default:
+ break;
+ }
+
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_WRITE_POINT_DATA_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_WRITE_POINT_DATA_32))
+ {
+ //uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_WRITE_POINT_DATA_1;
+ cmd->payload.point_value_cmd.type = buf_io_get8_fl_ap(buf);
+ buf += sens_itf_unpack_point_value(&cmd->payload.point_value_cmd, buf);
+ }
+
+ size = cmd->hdr.size + 2; // + crc
+ return size;
+}
+
+uint8_t sens_itf_pack_cmd_res(sens_itf_cmd_res_t *cmd, uint8_t *frame)
+{
+ uint8_t *buf = &frame[1];
+ uint8_t size = 0;
+ uint16_t crc;
+
+ buf_io_put8_tl_ap(cmd->hdr.addr, buf);
+ buf_io_put8_tl_ap(cmd->hdr.status, buf);
+
+ // only fill command when status is OK, otherwise an error will be reported
+ if (cmd->hdr.status == SENS_ITF_ANS_OK)
+ {
+ switch (cmd->hdr.addr)
+ {
+ case SENS_ITF_REGMAP_ITF_VERSION:
+ buf_io_put8_tl_ap(cmd->payload.itf_version_cmd.version, buf);
+ break;
+ case SENS_ITF_REGMAP_BRD_ID:
+ memcpy(buf, cmd->payload.brd_id_cmd.model, SENS_ITF_MODEL_NAME_SIZE);
+ buf += SENS_ITF_MODEL_NAME_SIZE;
+ memcpy(buf, cmd->payload.brd_id_cmd.manufactor, SENS_ITF_MANUF_NAME_SIZE);
+ buf += SENS_ITF_MODEL_NAME_SIZE;
+ buf_io_put32_tl_ap(cmd->payload.brd_id_cmd.sensor_id, buf);
+ buf_io_put8_tl_ap(cmd->payload.brd_id_cmd.hardware_revision, buf);
+ buf_io_put8_tl_ap(cmd->payload.brd_id_cmd.num_of_points, buf);
+ buf_io_put8_tl_ap(cmd->payload.brd_id_cmd.cabalities, buf);
+ break;
+ case SENS_ITF_REGMAP_BRD_STATUS:
+ buf_io_put8_tl_ap(cmd->payload.brd_status_cmd.status, buf);
+ break;
+ case SENS_ITF_REGMAP_BRD_CMD:
+ buf_io_put8_tl_ap(cmd->payload.command_res_cmd.status, buf);
+ break;
+ case SENS_ITF_REGMAP_READ_BAT_STATUS:
+ buf_io_put8_tl_ap(cmd->payload.bat_status_cmd.status, buf);
+ break;
+ case SENS_ITF_REGMAP_READ_BAT_CHARGE:
+ buf_io_put8_tl_ap(cmd->payload.bat_charge_cmd.charge, buf);
+ break;
+ case SENS_ITF_REGMAP_SVR_MAIN_ADDR:
+ case SENS_ITF_REGMAP_SVR_SEC_ADDR:
+ memcpy(buf, cmd->payload.svr_addr_cmd.addr, SENS_ITF_SERVER_ADDR_SIZE);
+ buf += SENS_ITF_SERVER_ADDR_SIZE;
+ break;
+ default:
+ break;
+ }
+
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_POINT_DESC_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_POINT_DESC_32))
+ {
+ //uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_POINT_DESC_1;
+ memcpy(buf, cmd->payload.point_desc_cmd.name, SENS_ITF_POINT_NAME_SIZE);
+ buf += SENS_ITF_POINT_NAME_SIZE;
+ buf_io_put8_tl_ap(cmd->payload.point_desc_cmd.type, buf);
+ buf_io_put8_tl_ap(cmd->payload.point_desc_cmd.unit, buf);
+ buf_io_put8_tl_ap(cmd->payload.point_desc_cmd.access_rights, buf);
+ buf_io_put32_tl_ap(cmd->payload.point_desc_cmd.sampling_time_x250ms, buf);
+ }
+
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_READ_POINT_DATA_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_READ_POINT_DATA_32))
+ {
+ //uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_READ_POINT_DATA_1;
+ buf_io_put8_tl_ap(cmd->payload.point_value_cmd.type,buf);
+ buf += sens_itf_pack_point_value(&cmd->payload.point_value_cmd, buf);
+ }
+ }
+
+ size = buf - frame;
+ buf_io_put8_tl(size, frame);
+ crc = crc16_calc(frame, size);
+ cmd->crc = crc;
+ cmd->hdr.size = size;
+ buf_io_put16_tl(crc, buf);
+
+ size += 2; // +crc
+ return size;
+}
+
+
+uint8_t sens_itf_unpack_cmd_res(sens_itf_cmd_res_t * cmd, uint8_t *frame, uint8_t frame_size)
+{
+ uint8_t size;
+ uint8_t *buf = frame;
+ uint16_t crc;
+ uint16_t frame_crc;
+
+ if (frame_size < 3)
+ {
+ cmd->hdr.status = SENS_ITF_ANS_ERROR;
+ return 0;
+ }
+
+ // minimal header decoding
+ cmd->hdr.size = buf_io_get8_fl_ap(buf);
+ cmd->hdr.addr = buf_io_get8_fl_ap(buf);
+ cmd->hdr.status = buf_io_get8_fl_ap(buf);
+
+ frame_crc = buf_io_get16_fl(&frame[cmd->hdr.size]);
+ crc = crc16_calc(frame, cmd->hdr.size);
+ cmd->crc = frame_crc;
+
+ if (frame_crc != crc)
+ {
+ //OS_UTIL_LOG(SENS_ITF_DBG_FRAME, ("Invalid CRC %04X <> %04X", frame_crc, crc));
+ cmd->hdr.status = SENS_ITF_ANS_CRC_ERROR;
+ return 0;
+ }
+
+ if (cmd->hdr.status != SENS_ITF_ANS_OK)
+ {
+ //OS_UTIL_LOG(SENS_ITF_DBG_FRAME, ("Response error %d", cmd->hdr.status));
+ return 0;
+ }
+
+ switch (cmd->hdr.addr)
+ {
+ case SENS_ITF_REGMAP_ITF_VERSION:
+ cmd->payload.itf_version_cmd.version = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_BRD_ID:
+ memcpy(cmd->payload.brd_id_cmd.model, buf, SENS_ITF_MODEL_NAME_SIZE);
+ buf += SENS_ITF_MODEL_NAME_SIZE;
+ memcpy(cmd->payload.brd_id_cmd.manufactor, buf, SENS_ITF_MANUF_NAME_SIZE);
+ buf += SENS_ITF_MODEL_NAME_SIZE;
+ cmd->payload.brd_id_cmd.sensor_id = buf_io_get32_fl_ap(buf);
+ cmd->payload.brd_id_cmd.hardware_revision = buf_io_get8_fl_ap(buf);
+ cmd->payload.brd_id_cmd.num_of_points = buf_io_get8_fl_ap(buf);
+ cmd->payload.brd_id_cmd.cabalities = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_BRD_STATUS:
+ cmd->payload.brd_status_cmd.status = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_BRD_CMD:
+ cmd->payload.command_res_cmd.status = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_READ_BAT_STATUS:
+ cmd->payload.bat_status_cmd.status = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_READ_BAT_CHARGE:
+ cmd->payload.bat_charge_cmd.charge = buf_io_get8_fl_ap(buf);
+ break;
+ case SENS_ITF_REGMAP_SVR_MAIN_ADDR:
+ case SENS_ITF_REGMAP_SVR_SEC_ADDR:
+ memcpy(cmd->payload.svr_addr_cmd.addr, buf, SENS_ITF_SERVER_ADDR_SIZE);
+ buf += SENS_ITF_SERVER_ADDR_SIZE;
+ break;
+ default:
+ break;
+ }
+
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_POINT_DESC_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_POINT_DESC_32))
+ {
+ memcpy(cmd->payload.point_desc_cmd.name, buf, SENS_ITF_POINT_NAME_SIZE);
+ buf += SENS_ITF_POINT_NAME_SIZE;
+ cmd->payload.point_desc_cmd.type = buf_io_get8_fl_ap(buf);
+ cmd->payload.point_desc_cmd.unit = buf_io_get8_fl_ap(buf);
+ cmd->payload.point_desc_cmd.access_rights = buf_io_get8_fl_ap(buf);
+ cmd->payload.point_desc_cmd.sampling_time_x250ms = buf_io_get32_fl_ap(buf);
+ }
+
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_READ_POINT_DATA_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_READ_POINT_DATA_32))
+ {
+ cmd->payload.point_value_cmd.type = buf_io_get8_fl_ap(buf);
+ buf += sens_itf_unpack_point_value(&cmd->payload.point_value_cmd, buf);
+ }
+
+ size = cmd->hdr.size + 2; // crc
+ return size;
+}
+
+uint8_t sens_itf_pack_cmd_req(sens_itf_cmd_req_t *cmd, uint8_t *frame)
+{
+ uint8_t *buf = &frame[1];
+ uint8_t size = 0;
+ uint16_t crc;
+
+ // address
+ // commands without arguments are handled only with this line
+ buf_io_put8_tl_ap(cmd->hdr.addr, buf);
+
+ switch (cmd->hdr.addr)
+ {
+ case SENS_ITF_REGMAP_BRD_CMD:
+ buf_io_put8_tl_ap(cmd->payload.command_cmd.cmd, buf);
+ break;
+ case SENS_ITF_REGMAP_WRITE_BAT_STATUS:
+ buf_io_put8_tl_ap(cmd->payload.bat_status_cmd.status, buf);
+ break;
+ case SENS_ITF_REGMAP_WRITE_BAT_CHARGE:
+ buf_io_put8_tl_ap(cmd->payload.bat_charge_cmd.charge, buf);
+ break;
+ case SENS_ITF_REGMAP_DSP_WRITE:
+ buf_io_put8_tl_ap(cmd->payload.write_display_cmd.line, buf);
+ memcpy(buf, cmd->payload.write_display_cmd.msg, SENS_ITF_DSP_MSG_MAX_SIZE);
+ buf += SENS_ITF_DSP_MSG_MAX_SIZE;
+ break;
+ case SENS_ITF_REGMAP_WPAN_STATUS:
+ buf_io_put8_tl_ap(cmd->payload.wpan_status_cmd.status,buf);
+ break;
+ case SENS_ITF_REGMAP_WPAN_STRENGTH:
+ buf_io_put8_tl_ap(cmd->payload.wpan_strength_cmd.strenght,buf);
+ break;
+ default:
+ break;
+ }
+
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_WRITE_POINT_DATA_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_WRITE_POINT_DATA_32))
+ {
+ buf_io_put8_tl_ap(cmd->payload.point_value_cmd.type, buf);
+ buf += sens_itf_pack_point_value(&cmd->payload.point_value_cmd, buf);
+ }
+
+ size = buf - frame;
+ buf_io_put8_tl(size, frame);
+ crc = crc16_calc(frame, size);
+ cmd->crc = crc;
+ cmd->hdr.size = size;
+ buf_io_put16_tl(crc, buf);
+
+ size += 2; // + crc
+
+ return size;
+}
diff -r 01c4d4d8febf -r acdf490d94a7 sens_itf/sens_itf.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_itf.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,403 @@
+/** @file */
+
+#ifndef __SENS_ITF_H__
+#define __SENS_ITF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SENS_ITF_LATEST_VERSION 0
+#define SENS_ITF_MAX_FRAME_SIZE 128
+#define SENS_ITF_DSP_MSG_MAX_SIZE 24
+#define SENS_ITF_MAX_POINTS 32
+#define SENS_ITF_SERVER_ADDR_SIZE 16
+#define SENS_ITF_MODEL_NAME_SIZE 8
+#define SENS_ITF_MANUF_NAME_SIZE 8
+#define SENS_ITF_POINT_NAME_SIZE 8
+
+/** Sensor interface standard datatypes */
+enum sens_itf_datatypes_e
+{
+ SENS_ITF_DT_U8 = 0x00, /**< 8 bits unsigned */
+ SENS_ITF_DT_S8 = 0x01, /**< 8 bits signed */
+ SENS_ITF_DT_U16 = 0x02, /**< 16 bits unsigned */
+ SENS_ITF_DT_S16 = 0x03, /**< 16 bits signed */
+ SENS_ITF_DT_U32 = 0x04, /**< 32 bits unsigned */
+ SENS_ITF_DT_S32 = 0x05, /**< 32 bits signed */
+ SENS_ITF_DT_U64 = 0x06, /**< 64 bits unsigned */
+ SENS_ITF_DT_S64 = 0x07, /**< 64 bits signed */
+ SENS_ITF_DT_FLOAT = 0x08, /**< IEEE 754 single precision */
+ SENS_ITF_DT_DOUBLE = 0x09, /**< IEEE 754 double precision */
+};
+
+/** Sensor interface register map */
+enum sens_itf_register_map_e
+{
+ SENS_ITF_REGMAP_ITF_VERSION = 0x00, /**< Sensor Board Interface Version */
+ SENS_ITF_REGMAP_BRD_ID = 0x01, /**< Sensor Board Identification */
+ SENS_ITF_REGMAP_BRD_STATUS = 0x02, /**< Sensor Board Status */
+ SENS_ITF_REGMAP_BRD_CMD = 0x03, /**< Sensor Board Command */
+ SENS_ITF_REGMAP_READ_BAT_STATUS = 0x04, /**< Read battery status */
+ SENS_ITF_REGMAP_WRITE_BAT_STATUS = 0x05, /**< Write battery status */
+ SENS_ITF_REGMAP_READ_BAT_CHARGE = 0x06, /**< Read battery charge(0 - 100 % ) */
+ SENS_ITF_REGMAP_WRITE_BAT_CHARGE = 0x07, /**< Write Battery charge(0 - 100 % ) */
+ SENS_ITF_REGMAP_WPAN_STATUS = 0x08, /**< Wireless network status */
+ SENS_ITF_REGMAP_WPAN_STRENGTH = 0x09, /**< Wireless network strength(RSSI, 0 to 100 % ) */
+ SENS_ITF_REGMAP_DSP_WRITE = 0x0A, /**< Write display (when display is available) */
+ SENS_ITF_REGMAP_SVR_MAIN_ADDR = 0x0B, /**< Main server address(IPv6) */
+ SENS_ITF_REGMAP_SVR_SEC_ADDR = 0x0C, /**< Secondary server address(IPv6) */
+
+ /*0x0D to 0x0F - Reserved(Should not be answered) */
+
+ SENS_ITF_REGMAP_POINT_DESC_1 = 0x10, /**< Sensor Point Description 1 */
+ SENS_ITF_REGMAP_POINT_DESC_2 = 0x11, /**< Sensor Point Description 2 */
+ SENS_ITF_REGMAP_POINT_DESC_3 = 0x12, /**< Sensor Point Description 3 */
+ SENS_ITF_REGMAP_POINT_DESC_4 = 0x13, /**< Sensor Point Description 4 */
+ SENS_ITF_REGMAP_POINT_DESC_5 = 0x14, /**< Sensor Point Description 5 */
+ SENS_ITF_REGMAP_POINT_DESC_6 = 0x15, /**< Sensor Point Description 6 */
+ SENS_ITF_REGMAP_POINT_DESC_7 = 0x16, /**< Sensor Point Description 7 */
+ SENS_ITF_REGMAP_POINT_DESC_8 = 0x17, /**< Sensor Point Description 8 */
+ SENS_ITF_REGMAP_POINT_DESC_9 = 0x18, /**< Sensor Point Description 9 */
+ SENS_ITF_REGMAP_POINT_DESC_10 = 0x19, /**< Sensor Point Description 10 */
+ SENS_ITF_REGMAP_POINT_DESC_11 = 0x1A, /**< Sensor Point Description 11 */
+ SENS_ITF_REGMAP_POINT_DESC_12 = 0x1B, /**< Sensor Point Description 12 */
+ SENS_ITF_REGMAP_POINT_DESC_13 = 0x1C, /**< Sensor Point Description 13 */
+ SENS_ITF_REGMAP_POINT_DESC_14 = 0x1D, /**< Sensor Point Description 14 */
+ SENS_ITF_REGMAP_POINT_DESC_15 = 0x1E, /**< Sensor Point Description 15 */
+ SENS_ITF_REGMAP_POINT_DESC_16 = 0x1F, /**< Sensor Point Description 16 */
+ SENS_ITF_REGMAP_POINT_DESC_17 = 0x20, /**< Sensor Point Description 17 */
+ SENS_ITF_REGMAP_POINT_DESC_18 = 0x21, /**< Sensor Point Description 18 */
+ SENS_ITF_REGMAP_POINT_DESC_19 = 0x22, /**< Sensor Point Description 19 */
+ SENS_ITF_REGMAP_POINT_DESC_20 = 0x23, /**< Sensor Point Description 20 */
+ SENS_ITF_REGMAP_POINT_DESC_21 = 0x24, /**< Sensor Point Description 21 */
+ SENS_ITF_REGMAP_POINT_DESC_22 = 0x25, /**< Sensor Point Description 22 */
+ SENS_ITF_REGMAP_POINT_DESC_23 = 0x26, /**< Sensor Point Description 23 */
+ SENS_ITF_REGMAP_POINT_DESC_24 = 0x27, /**< Sensor Point Description 24 */
+ SENS_ITF_REGMAP_POINT_DESC_25 = 0x28, /**< Sensor Point Description 25 */
+ SENS_ITF_REGMAP_POINT_DESC_26 = 0x29, /**< Sensor Point Description 26 */
+ SENS_ITF_REGMAP_POINT_DESC_27 = 0x2A, /**< Sensor Point Description 27 */
+ SENS_ITF_REGMAP_POINT_DESC_28 = 0x2B, /**< Sensor Point Description 28 */
+ SENS_ITF_REGMAP_POINT_DESC_29 = 0x2C, /**< Sensor Point Description 29 */
+ SENS_ITF_REGMAP_POINT_DESC_30 = 0x2D, /**< Sensor Point Description 30 */
+ SENS_ITF_REGMAP_POINT_DESC_31 = 0x2E, /**< Sensor Point Description 31 */
+ SENS_ITF_REGMAP_POINT_DESC_32 = 0x2F, /**< Sensor Point Description 32 */
+
+ SENS_ITF_REGMAP_READ_POINT_DATA_1 = 0x30, /**< Read Sensor Point Data 1 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_2 = 0x31, /**< Read Sensor Point Data 2 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_3 = 0x32, /**< Read Sensor Point Data 3 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_4 = 0x33, /**< Read Sensor Point Data 4 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_5 = 0x34, /**< Read Sensor Point Data 5 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_6 = 0x35, /**< Read Sensor Point Data 6 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_7 = 0x36, /**< Read Sensor Point Data 7 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_8 = 0x37, /**< Read Sensor Point Data 8 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_9 = 0x38, /**< Read Sensor Point Data 9 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_10 = 0x39, /**< Read Sensor Point Data 10 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_11 = 0x3A, /**< Read Sensor Point Data 11 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_12 = 0x3B, /**< Read Sensor Point Data 12 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_13 = 0x3C, /**< Read Sensor Point Data 13 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_14 = 0x3D, /**< Read Sensor Point Data 14 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_15 = 0x3E, /**< Read Sensor Point Data 15 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_16 = 0x3F, /**< Read Sensor Point Data 16 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_17 = 0x40, /**< Read Sensor Point Data 17 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_18 = 0x41, /**< Read Sensor Point Data 18 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_19 = 0x42, /**< Read Sensor Point Data 19 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_20 = 0x43, /**< Read Sensor Point Data 20 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_21 = 0x44, /**< Read Sensor Point Data 21 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_22 = 0x45, /**< Read Sensor Point Data 22 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_23 = 0x46, /**< Read Sensor Point Data 23 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_24 = 0x47, /**< Read Sensor Point Data 24 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_25 = 0x48, /**< Read Sensor Point Data 25 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_26 = 0x49, /**< Read Sensor Point Data 26 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_27 = 0x4A, /**< Read Sensor Point Data 27 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_28 = 0x4B, /**< Read Sensor Point Data 28 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_29 = 0x4C, /**< Read Sensor Point Data 29 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_30 = 0x4D, /**< Read Sensor Point Data 30 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_31 = 0x4E, /**< Read Sensor Point Data 31 */
+ SENS_ITF_REGMAP_READ_POINT_DATA_32 = 0x4F, /**< Read Sensor Point Data 32 */
+
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_1 = 0x50, /**< Write Sensor Point Data 1 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_2 = 0x51, /**< Write Sensor Point Data 2 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_3 = 0x52, /**< Write Sensor Point Data 3 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_4 = 0x53, /**< Write Sensor Point Data 4 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_5 = 0x54, /**< Write Sensor Point Data 5 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_6 = 0x55, /**< Write Sensor Point Data 6 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_7 = 0x56, /**< Write Sensor Point Data 7 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_8 = 0x57, /**< Write Sensor Point Data 8 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_9 = 0x58, /**< Write Sensor Point Data 9 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_10 = 0x59, /**< Write Sensor Point Data 10 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_11 = 0x5A, /**< Write Sensor Point Data 11 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_12 = 0x5B, /**< Write Sensor Point Data 12 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_13 = 0x5C, /**< Write Sensor Point Data 13 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_14 = 0x5D, /**< Write Sensor Point Data 14 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_15 = 0x5E, /**< Write Sensor Point Data 15 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_16 = 0x5F, /**< Write Sensor Point Data 16 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_17 = 0x60, /**< Write Sensor Point Data 17 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_18 = 0x61, /**< Write Sensor Point Data 18 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_19 = 0x62, /**< Write Sensor Point Data 19 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_20 = 0x63, /**< Write Sensor Point Data 20 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_21 = 0x64, /**< Write Sensor Point Data 21 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_22 = 0x65, /**< Write Sensor Point Data 22 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_23 = 0x66, /**< Write Sensor Point Data 23 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_24 = 0x67, /**< Write Sensor Point Data 24 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_25 = 0x68, /**< Write Sensor Point Data 25 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_26 = 0x69, /**< Write Sensor Point Data 26 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_27 = 0x6A, /**< Write Sensor Point Data 27 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_28 = 0x6B, /**< Write Sensor Point Data 28 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_29 = 0x6C, /**< Write Sensor Point Data 29 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_30 = 0x6D, /**< Write Sensor Point Data 30 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_31 = 0x6E, /**< Write Sensor Point Data 31 */
+ SENS_ITF_REGMAP_WRITE_POINT_DATA_32 = 0x6F, /**< Write Sensor Point Data 32 */
+
+ /* 0x70 to 0xFF - Reserved */
+};
+
+enum sens_itf_sensor_status_e
+{
+ SENS_ITF_SENSOR_STATUS_OK = 0,
+ SENS_ITF_SENSOR_STATUS_POINT_1 = 1,
+ SENS_ITF_SENSOR_STATUS_POINT_2 = 2,
+ SENS_ITF_SENSOR_STATUS_POINT_3 = 3,
+ SENS_ITF_SENSOR_STATUS_POINT_4 = 4,
+ SENS_ITF_SENSOR_STATUS_POINT_5 = 5,
+ SENS_ITF_SENSOR_STATUS_POINT_6 = 6,
+ SENS_ITF_SENSOR_STATUS_POINT_7 = 7,
+ SENS_ITF_SENSOR_STATUS_POINT_8 = 8,
+ SENS_ITF_SENSOR_STATUS_POINT_9 = 9,
+ SENS_ITF_SENSOR_STATUS_POINT_10 = 10,
+ SENS_ITF_SENSOR_STATUS_POINT_11 = 11,
+ SENS_ITF_SENSOR_STATUS_POINT_12 = 12,
+ SENS_ITF_SENSOR_STATUS_POINT_13 = 13,
+ SENS_ITF_SENSOR_STATUS_POINT_14 = 14,
+ SENS_ITF_SENSOR_STATUS_POINT_15 = 15,
+ SENS_ITF_SENSOR_STATUS_POINT_16 = 16,
+ SENS_ITF_SENSOR_STATUS_POINT_17 = 17,
+ SENS_ITF_SENSOR_STATUS_POINT_18 = 18,
+ SENS_ITF_SENSOR_STATUS_POINT_19 = 19,
+ SENS_ITF_SENSOR_STATUS_POINT_20 = 20,
+ SENS_ITF_SENSOR_STATUS_POINT_21 = 21,
+ SENS_ITF_SENSOR_STATUS_POINT_22 = 22,
+ SENS_ITF_SENSOR_STATUS_POINT_23 = 23,
+ SENS_ITF_SENSOR_STATUS_POINT_24 = 24,
+ SENS_ITF_SENSOR_STATUS_POINT_25 = 25,
+ SENS_ITF_SENSOR_STATUS_POINT_26 = 26,
+ SENS_ITF_SENSOR_STATUS_POINT_27 = 27,
+ SENS_ITF_SENSOR_STATUS_POINT_28 = 28,
+ SENS_ITF_SENSOR_STATUS_POINT_29 = 29,
+ SENS_ITF_SENSOR_STATUS_POINT_30 = 30,
+ SENS_ITF_SENSOR_STATUS_POINT_31 = 31,
+ SENS_ITF_SENSOR_STATUS_POINT_32 = 32,
+ /* 33 to 127 - reserved */
+ SENS_ITF_SENSOR_STATUS_GENERAL_SENSOR_FAILURE = 128,
+ /* 129 to 255 - reserved */
+};
+
+enum sens_itf_sensor_cmds_e
+{
+ SENS_ITF_SENSOR_CMD_RESET = 0,
+};
+
+enum sens_itf_ans_status_e
+{
+ SENS_ITF_ANS_OK = 0,
+ SENS_ITF_ANS_ERROR = 1,
+ SENS_ITF_ANS_CRC_ERROR = 2,
+ SENS_ITF_ANS_READY_ONLY = 3,
+ SENS_ITF_ANS_WRITE_ONLY = 4,
+ SENS_ITF_ANS_REGISTER_NOT_IMPLEMENTED = 5,
+};
+
+enum sens_itf_access_rights_e
+{
+ SENS_ITF_ACCESS_READ_ONLY = 0x01,
+ SENS_ITF_ACCESS_WRITE_ONLY = 0x02,
+ SENS_ITF_ACCESS_READ_WRITE = 0x03,
+};
+
+enum sens_itf_sensor_capabilities_e
+{
+ SENS_ITF_CAPABILITIES_BATTERY = 0x01,
+ SENS_ITF_CAPABILITIES_DISPLAY = 0x02,
+ SENS_ITF_CAPABILITIES_WPAN_STATUS = 0x04,
+ SENS_ITF_CAPABILITIES_BATTERY_STATUS = 0x08,
+};
+
+enum sens_itf_bat_status_e
+{
+ SENS_ITF_BAT_STATUS_CHARGED = 0x00,
+ SENS_ITF_BAT_STATUS_CHARGING = 0x01,
+ SENS_ITF_BAT_STATUS_DISCHARGING = 0x02,
+ SENS_ITF_BAT_STATUS_FAILURE = 0x03,
+};
+
+enum sens_itf_wpan_status_e
+{
+ SENS_ITF_WPAN_STATUS_CONNECTED = 0x00,
+ SENS_ITF_WPAN_STATUS_DISCONNECTED = 0x01,
+ SENS_ITF_WPAN_STATUS_CONNECTING = 0x02,
+};
+
+union sens_itf_point_data_u
+{
+ uint8_t u8;
+ int8_t s8;
+ uint16_t u16;
+ int16_t s16;
+ uint32_t u32;
+ int32_t s32;
+ uint64_t u64;
+ int64_t s64;
+ float fp32;
+ double fp64;
+};
+
+typedef struct sens_itf_cmd_bat_status_s
+{
+ uint8_t status;
+} sens_itf_cmd_bat_status_t;
+
+typedef struct sens_itf_cmd_bat_charge_s
+{
+ uint8_t charge;
+} sens_itf_cmd_bat_charge_t;
+
+typedef struct sens_itf_cmd_command_s
+{
+ uint8_t cmd;
+} sens_itf_cmd_command_t;
+
+typedef struct sens_itf_cmd_command_res_s
+{
+ uint8_t status;
+} sens_itf_cmd_command_res_t;
+
+typedef struct sens_itf_cmd_wpan_status_s
+{
+ uint8_t status;
+} sens_itf_cmd_wpan_status_t;
+
+typedef struct sens_itf_cmd_wpan_strenght_s
+{
+ uint8_t strenght;
+} sens_itf_cmd_wpan_strenght_t;
+
+typedef struct sens_itf_cmd_write_display_s
+{
+ uint8_t line;
+ uint8_t msg[SENS_ITF_DSP_MSG_MAX_SIZE];
+} sens_itf_cmd_write_display_t;
+
+typedef struct sens_itf_cmd_svr_addr_s
+{
+ uint8_t addr[SENS_ITF_SERVER_ADDR_SIZE];
+} sens_itf_cmd_svr_addr_t;
+
+typedef struct sens_itf_cmd_itf_version_s
+{
+ uint8_t version;
+} sens_itf_cmd_itf_version_t;
+
+typedef struct sens_itf_cmd_brd_id_s
+{
+ uint8_t model[SENS_ITF_MODEL_NAME_SIZE];
+ uint8_t manufactor[SENS_ITF_MANUF_NAME_SIZE];
+ uint32_t sensor_id;
+ uint8_t hardware_revision;
+ uint8_t num_of_points;
+ uint8_t cabalities;
+} sens_itf_cmd_brd_id_t;
+
+typedef struct sens_itf_cmd_brd_status_s
+{
+ uint8_t status;
+} sens_itf_cmd_brd_status_t;
+
+typedef struct sens_itf_cmd_point_desc_s
+{
+ uint8_t name[SENS_ITF_POINT_NAME_SIZE];
+ uint8_t type;
+ uint8_t unit;
+ uint8_t access_rights;
+ uint32_t sampling_time_x250ms;
+} sens_itf_cmd_point_desc_t;
+
+typedef struct sens_itf_cmd_point_s
+{
+ union sens_itf_point_data_u value;
+ uint8_t type;
+} sens_itf_cmd_point_t;
+
+typedef struct sens_itf_point_ctrl_s
+{
+ uint8_t num_of_points;
+ struct {
+ sens_itf_cmd_point_desc_t desc;
+ sens_itf_cmd_point_t value;
+ } points[SENS_ITF_MAX_POINTS];
+} sens_itf_point_ctrl_t;
+
+union sens_itf_cmds_u
+{
+ sens_itf_cmd_bat_status_t bat_status_cmd;
+ sens_itf_cmd_bat_charge_t bat_charge_cmd;
+ sens_itf_cmd_command_t command_cmd;
+ sens_itf_cmd_command_res_t command_res_cmd;
+ sens_itf_cmd_wpan_status_t wpan_status_cmd;
+ sens_itf_cmd_wpan_strenght_t wpan_strength_cmd;
+ sens_itf_cmd_write_display_t write_display_cmd;
+ sens_itf_cmd_svr_addr_t svr_addr_cmd;
+ sens_itf_cmd_itf_version_t itf_version_cmd;
+ sens_itf_cmd_brd_id_t brd_id_cmd;
+ sens_itf_cmd_brd_status_t brd_status_cmd;
+ sens_itf_cmd_point_desc_t point_desc_cmd;
+ sens_itf_cmd_point_t point_value_cmd;
+};
+
+typedef struct sens_itf_cmd_req_hdr_s
+{
+ uint8_t size;
+ uint8_t addr;
+} sens_itf_cmd_req_hdr_t;
+
+typedef struct sens_itf_cmd_res_hdr_s
+{
+ uint8_t size;
+ uint8_t status;
+ uint8_t addr;
+} sens_itf_cmd_res_hdr_t;
+
+typedef struct sens_itf_cmd_req_s
+{
+ sens_itf_cmd_req_hdr_t hdr;
+ union sens_itf_cmds_u payload;
+ uint16_t crc;
+} sens_itf_cmd_req_t;
+
+typedef struct sens_itf_cmd_res_s
+{
+ sens_itf_cmd_res_hdr_t hdr;
+ union sens_itf_cmds_u payload;
+ uint16_t crc;
+} sens_itf_cmd_res_t;
+
+
+//extern uint8_t sens_itf_send_cmd(sens_itf_cmd_req_t * cmd, sens_itf_cmd_res_t * ans);
+//extern int sens_itf_send_cmd_async(const sens_itf_cmd_req_t * const cmd, const sens_itf_cmd_res_t * ans);
+
+extern uint8_t sens_itf_mote_init(void);
+extern uint8_t sens_itf_sensor_init(void);
+extern void sens_itf_mote_main(void);
+
+extern uint8_t sens_itf_unpack_point_value(sens_itf_cmd_point_t *point, uint8_t *buf);
+extern uint8_t sens_itf_pack_point_value(const sens_itf_cmd_point_t *point, uint8_t *buf);
+
+extern uint8_t sens_itf_unpack_cmd_res(sens_itf_cmd_res_t *cmd, uint8_t *frame, uint8_t frame_size);
+extern uint8_t sens_itf_unpack_cmd_req(sens_itf_cmd_req_t *cmd, uint8_t *frame, uint8_t frame_size);
+extern uint8_t sens_itf_pack_cmd_res (sens_itf_cmd_res_t *cmd, uint8_t *frame);
+extern uint8_t sens_itf_pack_cmd_req (sens_itf_cmd_req_t *cmd, uint8_t *frame);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SENS_ITF_H__ */
diff -r 01c4d4d8febf -r acdf490d94a7 sens_itf/sens_itf_sensor.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_itf_sensor.cpp Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,477 @@
+#include <string.h>
+#include <stdint.h>
+#include "mbed.h"
+#include "sens_itf.h"
+#include "sens_util.h"
+#include "../util/buf_io.h"
+#include "../util/crc16.h"
+#include "../pt/pt.h"
+#include "SLCD.h"
+#include "MMA8451Q.h"
+
+#define SENS_ITF_SENSOR_DBG_FRAME 1
+#define SENS_ITF_DBG_FRAME 1
+#define SENS_ITF_SENSOR_NUM_OF_POINTS 5
+
+#define MMA8451_I2C_ADDRESS (0x1d<<1)
+
+static uint8_t main_svr_addr[SENS_ITF_SERVER_ADDR_SIZE];
+static uint8_t secon_svr_addr[SENS_ITF_SERVER_ADDR_SIZE];
+static uint8_t rx_frame[SENS_ITF_MAX_FRAME_SIZE];
+static volatile uint8_t num_rx_bytes;
+static Timeout rx_trmout_timer ;
+static Ticker acq_data_timer;
+static sens_itf_point_ctrl_t sensor_points;
+static sens_itf_cmd_brd_id_t board_info;
+static struct pt pt_updt;
+static struct pt pt_data;
+static volatile uint8_t frame_timeout;
+static volatile uint8_t acq_data ;
+static DigitalOut greenLED(LED1);
+static DigitalOut redLED(LED2);
+static AnalogIn lightSensor(PTE22);
+static SLCD sLCD;
+static Serial pcSerial(USBTX, USBRX);
+static MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
+static InterruptIn mode_switch(SW3);
+static volatile uint8_t view_mode;
+
+void scroll_message(char *message, unsigned char len)
+{
+ sLCD.All_Segments(0);
+
+ for (int start = 0; start < len - 4; start++)
+ {
+ for (int digit = 0; digit < 4; digit++)
+ sLCD.putc(message[start + digit]);
+ wait(0.4);
+ }
+}
+
+static void dump_frame(uint8_t *frame, uint8_t size)
+{
+ int n,m;
+ char buf[64];
+
+ buf[0] = buf[1] = buf[2] = buf[3] = ' ';
+
+ for(n = 0, m = 4; n < size ; n++, m+=3)
+ {
+ sprintf(&buf[m],"%02X_",frame[n]);
+ }
+
+ buf[m] = buf[m+1] = buf[m+2] = buf[m+3] = ' ';
+ buf[m+4] = '\0';
+
+ m +=4;
+ scroll_message(buf,m);
+
+}
+
+static uint8_t sens_itf_get_point_type(uint8_t point)
+{
+ return sensor_points.points[point].desc.type;
+}
+
+static uint8_t sens_itf_get_number_of_points(void)
+{
+ return SENS_ITF_SENSOR_NUM_OF_POINTS;
+}
+
+static sens_itf_cmd_point_desc_t *sens_itf_get_point_desc(uint8_t point)
+{
+ sens_itf_cmd_point_desc_t *d = 0;
+
+ if (point < sens_itf_get_number_of_points())
+ d = &sensor_points.points[point].desc;
+
+ return d;
+}
+
+static sens_itf_cmd_point_t *sens_itf_get_point_value(uint8_t point)
+{
+ sens_itf_cmd_point_t *v = 0;
+
+ if (point < sens_itf_get_number_of_points())
+ v = &sensor_points.points[point].value;
+
+ return v;
+}
+
+static uint8_t sens_itf_set_point_value(uint8_t point, sens_itf_cmd_point_t *v)
+{
+ uint8_t ret = 0;
+
+ if (point < sens_itf_get_number_of_points())
+ {
+ sensor_points.points[point].value = *v;
+ ret = 1;
+ }
+ else
+ {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static sens_itf_cmd_brd_id_t *sens_itf_get_board_info(void)
+{
+ return &board_info;
+}
+
+static uint8_t sens_itf_sensor_send_frame(uint8_t *frame, uint8_t size)
+{
+ //dump_frame(frame, size);
+
+ for(int n = 0 ; n < size ; n++)
+ pcSerial.putc((unsigned int )frame[n]);
+ //pcSerial.puts((char *)frame,size); // puts returns the size sent ?
+ return size;
+}
+
+static uint8_t sens_itf_sensor_check_register_map(sens_itf_cmd_req_t *cmd, sens_itf_cmd_res_t *ans, uint8_t *frame)
+{
+ uint8_t size = 0;
+ if ( // check global register map for valid address ranges
+ ((cmd->hdr.addr > SENS_ITF_REGMAP_SVR_SEC_ADDR) &&
+ (cmd->hdr.addr < SENS_ITF_REGMAP_POINT_DESC_1)) ||
+ (cmd->hdr.addr > SENS_ITF_REGMAP_WRITE_POINT_DATA_32) ||
+ // check local register map - reading
+ ((cmd->hdr.addr >= SENS_ITF_REGMAP_READ_POINT_DATA_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_READ_POINT_DATA_32) &&
+ ((cmd->hdr.addr - SENS_ITF_REGMAP_READ_POINT_DATA_1) >= sens_itf_get_number_of_points())) ||
+ // check local register map - writing
+ ((cmd->hdr.addr >= SENS_ITF_REGMAP_WRITE_POINT_DATA_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_WRITE_POINT_DATA_32) &&
+ ((cmd->hdr.addr - SENS_ITF_REGMAP_WRITE_POINT_DATA_1) >= sens_itf_get_number_of_points())))
+ {
+ sens_util_log(SENS_ITF_SENSOR_DBG_FRAME, "Invalid register address %02X",cmd->hdr.addr);
+ ans->hdr.status = SENS_ITF_ANS_REGISTER_NOT_IMPLEMENTED;
+ size = sens_itf_pack_cmd_res(ans, frame);
+ }
+ return size;
+}
+
+static uint8_t sens_itf_sensor_writings(sens_itf_cmd_req_t *cmd, sens_itf_cmd_res_t *ans, uint8_t *frame)
+{
+ uint8_t size = 0;
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_WRITE_POINT_DATA_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_WRITE_POINT_DATA_32))
+ {
+ uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_WRITE_POINT_DATA_1;
+ //sLCD.printf("R%dV%d",point,cmd->payload.point_value_cmd.value.u8);
+ //wait(0.5);
+ uint8_t acr = sens_itf_get_point_desc(point)->access_rights & SENS_ITF_ACCESS_WRITE_ONLY;
+
+ if (acr)
+ {
+ ans->hdr.status = SENS_ITF_ANS_OK;
+ sens_itf_set_point_value(point,&cmd->payload.point_value_cmd);
+ }
+ else
+ {
+ sens_util_log(SENS_ITF_SENSOR_DBG_FRAME, "Point %d does not allow writings",point);
+ ans->hdr.status = SENS_ITF_ANS_READY_ONLY;
+ }
+ size = sens_itf_pack_cmd_res(ans, frame);
+ }
+ return size;
+}
+
+static uint8_t sens_itf_sensor_readings(sens_itf_cmd_req_t *cmd, sens_itf_cmd_res_t *ans, uint8_t *frame)
+{
+ uint8_t size = 0;
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_READ_POINT_DATA_1) &&
+ (cmd->hdr.addr <= SENS_ITF_REGMAP_READ_POINT_DATA_32))
+ {
+ uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_READ_POINT_DATA_1;
+ uint8_t acr = sens_itf_get_point_desc(point)->access_rights & SENS_ITF_ANS_READY_ONLY;
+
+ if (acr)
+ {
+ ans->hdr.status = SENS_ITF_ANS_OK;
+ ans->payload.point_value_cmd = *sens_itf_get_point_value(point);
+ }
+ else
+ {
+ sens_util_log(SENS_ITF_SENSOR_DBG_FRAME, "Point %d does not allow readings",point);
+ ans->hdr.status = SENS_ITF_ANS_WRITE_ONLY;
+ }
+ size = sens_itf_pack_cmd_res(ans, frame);
+ }
+ return size;
+}
+
+static uint8_t sens_itf_check_other_cmds(sens_itf_cmd_req_t *cmd, sens_itf_cmd_res_t *ans, uint8_t *frame)
+{
+ uint8_t size = 0;
+ switch (cmd->hdr.addr)
+ {
+ case SENS_ITF_REGMAP_ITF_VERSION:
+ ans->payload.itf_version_cmd.version = SENS_ITF_LATEST_VERSION;
+ break;
+ case SENS_ITF_REGMAP_BRD_ID:
+ memcpy(&ans->payload.brd_id_cmd,sens_itf_get_board_info(),sizeof(sens_itf_cmd_brd_id_t));
+ break;
+ case SENS_ITF_REGMAP_BRD_STATUS:
+ ans->payload.brd_status_cmd.status = 0; // TBD
+ break;
+ case SENS_ITF_REGMAP_BRD_CMD:
+ ans->payload.command_res_cmd.status = 0; // TBD
+ break;
+ case SENS_ITF_REGMAP_READ_BAT_STATUS:
+ ans->payload.bat_status_cmd.status = 0; // TBD
+ break;
+ case SENS_ITF_REGMAP_READ_BAT_CHARGE:
+ ans->payload.bat_charge_cmd.charge = 100; // TBD
+ break;
+ case SENS_ITF_REGMAP_SVR_MAIN_ADDR:
+ memcpy(ans->payload.svr_addr_cmd.addr,main_svr_addr, SENS_ITF_SERVER_ADDR_SIZE);
+ break;
+ case SENS_ITF_REGMAP_SVR_SEC_ADDR:
+ memcpy(ans->payload.svr_addr_cmd.addr,secon_svr_addr, SENS_ITF_SERVER_ADDR_SIZE);
+ break;
+ default:
+ break;
+
+ }
+
+ if ((cmd->hdr.addr >= SENS_ITF_REGMAP_POINT_DESC_1) && (cmd->hdr.addr <= SENS_ITF_REGMAP_POINT_DESC_32))
+ {
+ uint8_t point = cmd->hdr.addr - SENS_ITF_REGMAP_POINT_DESC_1;
+ memcpy(&ans->payload.point_desc_cmd, &sensor_points.points[point].desc, sizeof(sens_itf_cmd_point_desc_t));
+ }
+
+ ans->hdr.status = SENS_ITF_ANS_OK;
+ size = sens_itf_pack_cmd_res(ans, frame);
+ return size;
+}
+static void sens_itf_process_cmd(uint8_t *frame, uint8_t num_rx_bytes)
+{
+ uint8_t ret;
+ uint8_t size = 0;
+ sens_itf_cmd_req_t cmd;
+ sens_itf_cmd_res_t ans;
+
+ ret = sens_itf_unpack_cmd_req(&cmd, frame, num_rx_bytes);
+
+ if (ret > 0)
+ {
+ ans.hdr.addr = cmd.hdr.addr;
+
+ size = sens_itf_sensor_check_register_map(&cmd, &ans,frame);
+ if (size == 0)
+ size = sens_itf_sensor_writings(&cmd, &ans,frame);
+
+ if (size == 0)
+ size = sens_itf_sensor_readings(&cmd, &ans,frame);
+
+ if (size == 0)
+ size = sens_itf_check_other_cmds(&cmd, &ans,frame);
+
+ if (size == 0)
+ {
+ ans.hdr.status = SENS_ITF_ANS_ERROR;
+ sLCD.printf(" D");
+ }
+
+ size = sens_itf_pack_cmd_res(&ans,frame);
+ sens_itf_sensor_send_frame(frame, size);
+ }
+}
+
+void sens_itf_init_point_db(void)
+{
+ uint8_t n;
+ char *point_names[SENS_ITF_POINT_NAME_SIZE] = { "LIGHT", "LEDG", "ACCX", "ACCY", "ACCXZ" };
+ uint8_t data_types[SENS_ITF_POINT_NAME_SIZE] = {SENS_ITF_DT_U8, SENS_ITF_DT_U8, SENS_ITF_DT_FLOAT, SENS_ITF_DT_FLOAT, SENS_ITF_DT_FLOAT};
+ uint8_t access_rights[SENS_ITF_POINT_NAME_SIZE] = { SENS_ITF_ACCESS_READ_ONLY, SENS_ITF_ACCESS_WRITE_ONLY, SENS_ITF_ACCESS_READ_ONLY,
+ SENS_ITF_ACCESS_READ_ONLY, SENS_ITF_ACCESS_READ_ONLY};
+ uint32_t sampling_time[SENS_ITF_POINT_NAME_SIZE] = {4*10, 0, 4*15, 4*20, 4*25};
+
+ memset(&sensor_points, 0, sizeof(sensor_points));
+ memset(&board_info, 0, sizeof(board_info));
+
+ strcpy((char *)board_info.model, "KL46Z");
+ strcpy((char *)board_info.manufactor, "TESLA");
+ board_info.sensor_id = 0xDEADBEEF;
+ board_info.hardware_revision = 0x01;
+ board_info.num_of_points = SENS_ITF_SENSOR_NUM_OF_POINTS;
+ board_info.cabalities = SENS_ITF_CAPABILITIES_DISPLAY |
+ SENS_ITF_CAPABILITIES_WPAN_STATUS |
+ SENS_ITF_CAPABILITIES_BATTERY_STATUS;
+
+ sensor_points.num_of_points = SENS_ITF_SENSOR_NUM_OF_POINTS;
+
+ for (n = 0; n < SENS_ITF_SENSOR_NUM_OF_POINTS; n++)
+ {
+ strcpy((char *)sensor_points.points[n].desc.name, point_names[n]);
+ sensor_points.points[n].desc.type = data_types[n];
+ sensor_points.points[n].desc.unit = 0; // TDB
+ sensor_points.points[n].desc.access_rights = access_rights[n];
+ sensor_points.points[n].desc.sampling_time_x250ms = sampling_time[n];
+ sensor_points.points[n].value.type = data_types[n];
+ }
+}
+
+static void sens_itf_rx_tmrout_timer_func(void)
+{
+ //greenLED = greenLED == 1 ? 0 : 1;
+ frame_timeout = 1;
+}
+
+static void sens_itf_acq_data_timer_func(void)
+{
+ redLED = redLED == 1 ? 0 : 1;
+ acq_data = 1;
+}
+
+static void sens_itf_rx_tmrout_timer_reesched(void)
+{
+ rx_trmout_timer.detach();
+ rx_trmout_timer.attach_us(sens_itf_rx_tmrout_timer_func,500*1000);
+}
+
+// Serial or SPI interrupt, called when a new byte is received
+static void sens_itf_sensor_rx_byte(void)
+{
+ uint8_t value;
+
+ // DISABLE INTERRUPTS
+ if (frame_timeout)
+ return;
+
+ value = (uint8_t) pcSerial.getc();
+
+ if (num_rx_bytes < SENS_ITF_MAX_FRAME_SIZE)
+ rx_frame[num_rx_bytes] = value;
+
+ num_rx_bytes++;
+ if (num_rx_bytes >= SENS_ITF_MAX_FRAME_SIZE)
+ num_rx_bytes = 0;
+
+ sens_itf_rx_tmrout_timer_reesched();
+ // ENABLE INTERRUPTS
+}
+
+uint8_t sens_itf_sensor_init(void)
+{
+
+ sens_itf_init_point_db();
+ memcpy(main_svr_addr,"1212121212121212",SENS_ITF_SERVER_ADDR_SIZE);
+ memcpy(secon_svr_addr,"aabbccddeeff1122",SENS_ITF_SERVER_ADDR_SIZE);
+ num_rx_bytes = 0;
+ acq_data = 0;
+ frame_timeout = 0;
+ greenLED = 0;
+ redLED = 1;
+ sens_itf_rx_tmrout_timer_reesched();
+ acq_data_timer.attach(sens_itf_acq_data_timer_func,2);
+ pcSerial.attach(sens_itf_sensor_rx_byte);
+
+ return 1;
+}
+
+static int pt_data_func(struct pt *pt)
+{
+ PT_BEGIN(pt);
+
+ while (1)
+ {
+ // wait a frame timeout
+ PT_WAIT_UNTIL(pt, frame_timeout == 1);
+
+ if (num_rx_bytes > 0)
+ {
+ // process it
+ sens_itf_process_cmd(rx_frame, num_rx_bytes);
+ num_rx_bytes = 0;
+ }
+
+ // restart reception
+ frame_timeout = 0;
+ sens_itf_rx_tmrout_timer_reesched();
+ }
+
+ PT_END(pt);
+}
+
+static int pt_updt_func(struct pt *pt)
+{
+ PT_BEGIN(pt);
+
+ while (1)
+ {
+ char buf[5];
+ uint8_t v;
+
+ // wait job
+ PT_WAIT_UNTIL(pt, acq_data == 1);
+
+ v = (uint8_t)(lightSensor.read()*100);
+ sensor_points.points[0].value.value.u8 = v;
+ greenLED = sensor_points.points[1].value.value.u8;
+ sensor_points.points[2].value.value.fp32 = 1.0 - abs(acc.getAccX());
+ sensor_points.points[3].value.value.fp32 = 1.0 - abs(acc.getAccY());
+ sensor_points.points[4].value.value.fp32 = 1.0 - abs(acc.getAccZ());
+
+ sLCD.All_Segments(0);
+ switch(view_mode)
+ {
+ case 0:
+ sprintf(buf,"L %2d",v);
+ sLCD.printf("%s",buf);
+ break;
+ case 1:
+ sprintf(buf,"%4d",(uint16_t) (sensor_points.points[2].value.value.fp32*1000));
+ sLCD.printf("%s",buf);
+ break;
+ case 2:
+ sprintf(buf,"%4d",(uint16_t) (sensor_points.points[3].value.value.fp32*1000));
+ sLCD.printf("%s",buf);
+ break;
+ case 3:
+ sprintf(buf,"%4d",(uint16_t) (sensor_points.points[4].value.value.fp32*1000));
+ sLCD.printf("%s",buf);
+ break;
+ default:
+ break;
+ }
+
+ acq_data = 0;
+ }
+
+ PT_END(pt);
+}
+
+void set_mode(void)
+{
+ view_mode = ++view_mode > 3 ? 0 : view_mode;
+}
+
+void main(void)
+{
+ frame_timeout = 0;
+ acq_data = 0;
+ view_mode = 0;
+
+ sLCD.All_Segments(0);
+ sLCD.DP2(0);
+ sLCD.printf("INIT");
+ pcSerial.baud(115200);
+ sens_itf_sensor_init();
+
+ mode_switch.rise(set_mode);
+
+ PT_INIT(&pt_data);
+ PT_INIT(&pt_updt);
+
+
+ while(1)
+ {
+ pt_data_func(&pt_data);
+ pt_updt_func(&pt_updt);
+ }
+}
+
diff -r 01c4d4d8febf -r acdf490d94a7 sens_itf/sens_util.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_util.c Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,81 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "sens_util.h"
+
+#define MAX_LOG_BUF 256
+static char buffer[MAX_LOG_BUF];
+
+static volatile int sens_util_log_started = 0;
+
+void sens_util_assert(int cond)
+{
+ assert(cond);
+}
+
+const uint8_t *sens_util_strip_path(const uint8_t *filename)
+{
+ int pos;
+
+ pos = strlen(filename) - 1; // avoiding null terminator
+
+ while( (filename[pos] != '\\') && (pos > 0) )
+ pos--;
+
+ if(pos != 0)
+ pos++; // removing "\"
+
+ return &filename[pos];
+}
+
+void sens_util_log(int cond, const uint8_t *line, ...)
+{
+ va_list argp;
+
+ if((!cond) || (!sens_util_log_started))
+ return;
+
+ va_start(argp, line);
+ vsnprintf(buffer,MAX_LOG_BUF,line, argp);
+ va_end(argp);
+
+ buffer[MAX_LOG_BUF-1] = '\0';
+
+ // TODO
+ // define destination for this buffer: ethernet, serial, console, syslog ...
+ //
+ printf("%s",buffer);
+}
+
+void sens_util_dump_frame(const uint8_t * const data, int len)
+{
+ int i, j, k;
+ uint8_t buf[50];
+
+ for(k = 0 ; k < len ; k += 16)
+ {
+ for(i = k, j = 0 ; ( i< (k+16) ) && ( i < len ) ; i++, j+=3 )
+ sprintf((char *)&buf[j],"%02X ",data[i]);
+ buf[j] = '\0';
+ sens_util_log(1,"%s",buf);
+ }
+}
+
+int sens_util_log_stop(void)
+{
+ if(sens_util_log_started)
+ sens_util_log_started = 0;
+
+ return 0;
+}
+
+int sens_util_log_start(void)
+{
+ if(!sens_util_log_started)
+ sens_util_log_started = 1;
+
+ return 0;
+}
diff -r 01c4d4d8febf -r acdf490d94a7 sens_itf/sens_util.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sens_itf/sens_util.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,78 @@
+/**
+ @file sens_util.h
+ @brief Utilities routines
+*/
+#ifndef __SENS_UTIL__
+#define __SENS_UTIL__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ @defgroup OSUTIL Utilities
+ @ingroup OSGLOBALS
+ @{
+*/
+
+/**
+ Assertion like function.
+
+ @param cond Assertion condition.
+ */
+extern void sens_util_assert(int cond);
+
+/**
+ Message log utility.
+
+ @param cond Logs only when the condition is true.
+ @param line Variable parameters list like printf.
+*/
+extern void sens_util_log(int cond, const uint8_t *line, ...);
+
+/**
+ Start log.
+
+ @retval 1 Log not started.
+ @retval 0 Log started.
+*/
+extern int sens_util_log_start(void);
+
+/**
+ Stop log .
+
+@retval 1 Log not stopped.
+@retval 0 Log stopped.
+*/
+extern int sens_util_log_stop(void);
+
+/**
+ Remove path and return only the file name.
+
+ @param filename file with full path name
+ @return filename without path
+*/
+extern const uint8_t *sens_util_strip_path(const uint8_t *filename);
+
+/**
+ Print a buffer in hexadecimal (16 byte per row).
+
+ @param data Data to be printed.
+ @param len Data length.
+*/
+extern void sens_util_dump_frame(const uint8_t *const data, int len);
+
+/**
+ @def SENS_UTIL_ASSERT
+ @brief Assertion macro
+*/
+#define SENS_UTIL_ASSERT(cond) sens_util_assert( !!(cond) )
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SENS_UTIL__ */
+
diff -r 01c4d4d8febf -r acdf490d94a7 util.lib
--- a/util.lib Mon Apr 07 18:38:15 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-util#55459711bbbf
diff -r 01c4d4d8febf -r acdf490d94a7 util/buf_io.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/buf_io.c Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,395 @@
+#include <stdint.h>
+#include "buf_io.h"
+
+/* --- swap functions ---------------------------- */
+
+uint16_t buf_io_swap16(uint16_t orig_value)
+{
+ uint16_t value = ((orig_value & 0x00FF) << 8) |
+ ((orig_value & 0xFF00) >> 8) ;
+ return value;
+}
+
+uint32_t buf_io_swap32(uint32_t orig_value)
+{
+ uint32_t value = ((orig_value & 0x000000FF) << 24) |
+ ((orig_value & 0x0000FF00) << 8 ) |
+ ((orig_value & 0x00FF0000) >> 8 ) |
+ ((orig_value & 0xFF000000) >> 24);
+ return value;
+}
+
+void buf_io_swap16p(uint8_t *buf)
+{
+ uint8_t value[2];
+ value[1] = *buf++;
+ value[0] = *buf++;
+ *--buf = value[1];
+ *--buf = value[0];
+}
+
+void buf_io_swap32p(uint8_t *buf)
+{
+ uint8_t value[4];
+ value[3] = *buf++;
+ value[2] = *buf++;
+ value[1] = *buf++;
+ value[0] = *buf++;
+ *--buf = value[3];
+ *--buf = value[2];
+ *--buf = value[1];
+ *--buf = value[0];
+}
+
+uint8_t buf_io_swap8b(uint8_t orig_value)
+{
+ uint8_t value = ((orig_value & 0x01) << 7) |
+ ((orig_value & 0x02) << 5) |
+ ((orig_value & 0x04) << 3) |
+ ((orig_value & 0x08) << 1) |
+ ((orig_value & 0x10) >> 1) |
+ ((orig_value & 0x20) >> 3) |
+ ((orig_value & 0x40) >> 5) |
+ ((orig_value & 0x80) >> 7);
+ return value;
+}
+
+/* --- 8 bits GET functions ---------------------------- */
+
+uint8_t buf_io_get8_fl(uint8_t *buf)
+{
+ return buf[0];
+}
+
+uint8_t buf_io_get8_fb(uint8_t *buf)
+{
+ return buf[0];
+}
+
+uint8_t buf_io_get8_fl_apr(uint8_t **buf)
+{
+ uint8_t value = buf_io_get8_fl(*buf);
+ *buf += 1;
+ return value;
+}
+
+uint8_t buf_io_get8_fb_apr(uint8_t **buf)
+{
+ uint8_t value = buf_io_get8_fb(*buf);
+ *buf += 1;
+ return value;
+}
+
+/* --- 16 bits GET functions ---------------------------- */
+
+uint16_t buf_io_get16_fl(uint8_t *buf)
+{
+ uint16_t value = buf[0] | (buf[1] << 8);
+ return value;
+}
+
+uint16_t buf_io_get16_fb(uint8_t *buf)
+{
+ uint16_t value = buf[1] | (buf[0] << 8);
+ return value;
+}
+
+uint16_t buf_io_get16_fl_apr(uint8_t **buf)
+{
+ uint16_t value = buf_io_get16_fl(*buf);
+ *buf += 2;
+ return value;
+}
+
+uint16_t buf_io_get16_fb_apr(uint8_t **buf)
+{
+ uint16_t value = buf_io_get16_fb(*buf);
+ *buf += 2;
+ return value;
+}
+
+/* --- 32 bits GET functions ---------------------------- */
+
+uint32_t buf_io_get32_fl(uint8_t *buf)
+{
+ uint32_t value = buf[0] | (buf[1] << 8 ) | (buf[2] << 16) | (buf[3] << 24);
+ return value;
+}
+
+uint32_t buf_io_get32_fb(uint8_t *buf)
+{
+ uint32_t value = buf[3] | (buf[2] << 8 ) | (buf[1] << 16) | (buf[0] << 24);
+ return value;
+}
+
+uint32_t buf_io_get32_fl_apr(uint8_t **buf)
+{
+ uint32_t value = buf_io_get32_fl(*buf);
+ *buf += 4;
+ return value;
+}
+
+uint32_t buf_io_get32_fb_apr(uint8_t **buf)
+{
+ uint32_t value = buf_io_get32_fb(*buf);
+ *buf += 4;
+ return value;
+}
+
+/* --- 64 bits GET functions ---------------------------- */
+
+uint64_t buf_io_get64_fl(uint8_t *buf)
+{
+ uint8_t *p1 = buf;
+ uint8_t *p2 = (buf + 4);
+ uint64_t v1 = p1[0] | (p1[1] << 8 ) | (p1[2] << 16) | (p1[3] << 24);
+ uint64_t v2 = p2[0] | (p2[1] << 8 ) | (p2[2] << 16) | (p2[3] << 24);
+ uint64_t value = (v2 << 32) | v1;
+ return value;
+}
+
+uint64_t buf_io_get64_fb(uint8_t *buf)
+{
+ uint8_t *p1 = buf;
+ uint8_t *p2 = (buf + 4);
+ uint64_t v1 = p1[3] | (p1[2] << 8 ) | (p1[1] << 16) | (p1[0] << 24);
+ uint64_t v2 = p2[3] | (p2[2] << 8 ) | (p2[1] << 16) | (p2[0] << 24);
+ uint64_t value = (v1 << 32) | v2;
+ return value;
+}
+
+uint64_t buf_io_get64_fl_apr(uint8_t **buf)
+{
+ uint64_t value = buf_io_get64_fl(*buf);
+ *buf += 8;
+ return value;
+}
+
+uint64_t buf_io_get64_fb_apr(uint8_t **buf)
+{
+ uint64_t value = buf_io_get64_fb(*buf);
+ *buf += 8;
+ return value;
+}
+
+/* --- float GET functions ---------------------------- */
+
+float buf_io_getf_fl(uint8_t *buf)
+{
+ uint32_t value = buf_io_get32_fl(buf);
+ return *((float* )&value);
+}
+
+float buf_io_getf_fb(uint8_t *buf)
+{
+ uint32_t value = buf_io_get32_fb(buf);
+ return *((float* )&value);
+}
+
+float buf_io_getf_fl_apr(uint8_t **buf)
+{
+ float value = buf_io_getf_fl(*buf);
+ (*buf) += 4;
+ return value;
+}
+
+float buf_io_getf_fb_apr(uint8_t **buf)
+{
+ float value = buf_io_getf_fb(*buf);
+ (*buf) += 4;
+ return value;
+}
+
+/* --- double GET functions ---------------------------- */
+
+double buf_io_getd_fl(uint8_t *buf)
+{
+ uint64_t value = buf_io_get64_fl(buf);
+ return *((double* )&value);
+}
+
+double buf_io_getd_fb(uint8_t *buf)
+{
+ uint64_t value = buf_io_get64_fb(buf);
+ return *((double* )&value);
+}
+
+double buf_io_getd_fl_apr(uint8_t **buf)
+{
+ double value = buf_io_getd_fl(*buf);
+ (*buf) += 8;
+ return value;
+}
+
+double buf_io_getd_fb_apr(uint8_t **buf)
+{
+ double ret = buf_io_getd_fb(*buf);
+ (*buf) += 8;
+ return ret;
+}
+
+/* --- 8 bits PUT functions ---------------------------- */
+
+void buf_io_put8_tl(uint8_t value, uint8_t *buf)
+{
+ buf[0] = value;
+}
+
+void buf_io_put8_tb(uint8_t value, uint8_t *buf)
+{
+ buf[0] = value;
+}
+
+void buf_io_put8_tl_apr(uint8_t value, uint8_t **buf)
+{
+ buf_io_put8_tl(value,*buf);
+ *buf += 1;
+}
+
+void buf_io_put8_tb_apr(uint8_t value, uint8_t **buf)
+{
+ buf_io_put8_tb(value,*buf);
+ *buf += 1;
+}
+
+/* --- 16 bits PUT functions ---------------------------- */
+
+void buf_io_put16_tl(uint16_t value, uint8_t *buf)
+{
+ buf[0] = (uint8_t)(value );
+ buf[1] = (uint8_t)(value >> 8);
+}
+
+void buf_io_put16_tb(uint16_t value, uint8_t *buf)
+{
+ buf[1] = (uint8_t)(value );
+ buf[0] = (uint8_t)(value >> 8);
+}
+
+void buf_io_put16_tl_apr(uint16_t value, uint8_t **buf)
+{
+ buf_io_put16_tl(value,*buf);
+ *buf += 2;
+}
+
+void buf_io_put16_tb_apr(uint16_t value, uint8_t **buf)
+{
+ buf_io_put16_tb(value,*buf);
+ *buf += 2;
+}
+
+/* --- 32 bits PUT functions ---------------------------- */
+
+void buf_io_put32_tl(uint32_t value, uint8_t *buf)
+{
+ buf[0] = (uint8_t)(value );
+ buf[1] = (uint8_t)(value >> 8 );
+ buf[2] = (uint8_t)(value >> 16);
+ buf[3] = (uint8_t)(value >> 24);
+}
+
+void buf_io_put32_tb(uint32_t value, uint8_t *buf)
+{
+ buf[3] = (uint8_t)(value );
+ buf[2] = (uint8_t)(value >> 8 );
+ buf[1] = (uint8_t)(value >> 16);
+ buf[0] = (uint8_t)(value >> 24);
+}
+
+void buf_io_put32_tl_apr(uint32_t value, uint8_t **buf)
+{
+ buf_io_put32_tl(value,*buf);
+ *buf += 4;
+}
+
+void buf_io_put32_tb_apr(uint32_t value, uint8_t **buf)
+{
+ buf_io_put32_tb(value,*buf);
+ *buf += 4;
+}
+
+/* --- 64 bits PUT functions ---------------------------- */
+
+void buf_io_put64_tl(uint64_t value, uint8_t *buf)
+{
+ buf[0] = (uint8_t)(value );
+ buf[1] = (uint8_t)(value >> 8 );
+ buf[2] = (uint8_t)(value >> 16);
+ buf[3] = (uint8_t)(value >> 24);
+ buf[4] = (uint8_t)(value >> 32);
+ buf[5] = (uint8_t)(value >> 40);
+ buf[6] = (uint8_t)(value >> 48);
+ buf[7] = (uint8_t)(value >> 56);
+}
+
+void buf_io_put64_tb(uint64_t value, uint8_t *buf)
+{
+ buf[7] = (uint8_t)(value );
+ buf[6] = (uint8_t)(value >> 8 );
+ buf[5] = (uint8_t)(value >> 16);
+ buf[4] = (uint8_t)(value >> 24);
+ buf[3] = (uint8_t)(value >> 32);
+ buf[2] = (uint8_t)(value >> 40);
+ buf[1] = (uint8_t)(value >> 48);
+ buf[0] = (uint8_t)(value >> 56);
+}
+
+void buf_io_put64_tl_apr(uint64_t value, uint8_t **buf)
+{
+ buf_io_put64_tl(value,*buf);
+ *buf += 8;
+}
+
+void buf_io_put64_tb_apr(uint64_t value, uint8_t **buf)
+{
+ buf_io_put64_tb(value,*buf);
+ *buf += 8;
+}
+
+/* --- float PUT functions ---------------------------- */
+
+void buf_io_putf_tl(float value, uint8_t *buf)
+{
+ buf_io_put32_tl(*((uint32_t*) &value),buf);
+}
+
+void buf_io_putf_tb(float value, uint8_t *buf)
+{
+ buf_io_put32_tb(*((uint32_t*) &value),buf);
+}
+
+void buf_io_putf_tl_apr(float value, uint8_t **buf)
+{
+ buf_io_putf_tl(value,*buf);
+ *buf += 4;
+}
+
+void buf_io_putf_tb_apr(float value, uint8_t **buf)
+{
+ buf_io_putf_tb(value,*buf);
+ *buf += 4;
+}
+
+/* --- double PUT functions ---------------------------- */
+
+void buf_io_putd_tl(double value, uint8_t *buf)
+{
+ buf_io_put64_tl(*((uint64_t*) &value),buf);
+}
+
+void buf_io_putd_tb(double value, uint8_t *buf)
+{
+ buf_io_put64_tb(*((uint64_t*) &value),buf);
+}
+
+void buf_io_putd_tl_apr(double value, uint8_t **buf)
+{
+ buf_io_putd_tl(value,*buf);
+ *buf += 8;
+}
+
+void buf_io_putd_tb_apr(double value, uint8_t **buf)
+{
+ buf_io_putd_tb(value,*buf);
+ *buf += 8;
+}
diff -r 01c4d4d8febf -r acdf490d94a7 util/buf_io.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/buf_io.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,183 @@
+/**
+@file buf_io.c
+
+Several functions for handling data in buffers.
+
+Basic functions:
+
+buf_io_[get|put][8|16|32|64|f|d]_[f|t][b|l]_ap[r]
+
+Notation:
+
+8|16|32|64|f|d = data size (f for float, d for double)
+[f|t][b|l] = from/to big/little
+ap[r] = add pointer [reference] at the end
+
+Check buf_io.c for a proper implementation of these functions for your platform.
+*/
+
+#ifndef __BUF_IO__
+#define __BUF_IO__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Pointer size */
+#define POINTER_SIZE (sizeof(void *))
+
+/** Number of elements in a array */
+#define NUM_OF_ELEMENTS_IN_ARRAY(a) (sizeof(a)/sizeof(a[0]))
+
+/**
+ @name next/prev macro functions
+ Next/previous aligned address, avoiding data aborts in buffer operations.
+ @{
+*/
+#define __next_aligned_addr32(x) (((x) + 0x03) & 0xFFFFFFFC)
+#define __next_aligned_addr16(x) (((x) + 0x01) & 0xFFFFFFFE)
+#define __prev_aligned_addr32(x) ((x) & 0xFFFFFFFC)
+#define __prev_aligned_addr16(x) ((x) & 0xFFFFFFFE)
+/** @} */
+
+/**
+ @name swap functions
+ Swap operations.
+ @{
+*/
+
+/**
+ Swaps a 16 bits unsigned integer.
+ @param ucShort 16 bits unsigned integer to be swapped
+ @return 16 bits unsigned integer swapped
+ @{
+ */
+uint16_t buf_io_swap16 (uint16_t usShort);
+
+/**
+ Swaps a 32 bits unsigned integer.
+ @param ulLong 32 bits unsigned integer to be swapped
+ @return 32 bits unsigned integer swapped
+ @{
+ */
+uint32_t buf_io_swap32 (uint32_t ulLong);
+
+/**
+ Swaps a 16 bits unsigned integer inside a buffer.
+ @param pucPtr Pointer where 16 bits unsigned integer is stored.
+*/
+void buf_io_swap16p(uint8_t *pucPtr);
+
+/**
+ Swaps a 32 bits unsigned integer inside a buffer.
+ @param pucPtr Pointer where 32 bits unsigned integer is stored.
+*/
+void buf_io_swap32p(uint8_t *pucPtr);
+
+/**
+ Swaps 8 bits unsigned integer in a byte.
+ @param ucChar 8 bits unsigned integer to be bit swapped
+ @return 8 bits unsigned integer swapped
+*/
+uint8_t buf_io_swap8b (uint8_t ucChar);
+/** @} */
+
+/**
+ @name endianess dependent functions (GET)
+ @{
+*/
+uint8_t buf_io_get8_fl (uint8_t *buf);
+uint8_t buf_io_get8_fb (uint8_t *buf);
+uint8_t buf_io_get8_fl_apr (uint8_t **buf);
+uint8_t buf_io_get8_fb_apr (uint8_t **buf);
+#define buf_io_get8_fl_ap(x) buf_io_get8_fl_apr(&x)
+#define buf_io_get8_fb_ap(x) buf_io_get8_fb_apr(&x)
+
+uint16_t buf_io_get16_fl (uint8_t *buf);
+uint16_t buf_io_get16_fb (uint8_t *buf);
+uint16_t buf_io_get16_fl_apr (uint8_t **buf);
+uint16_t buf_io_get16_fb_apr (uint8_t **buf);
+#define buf_io_get16_fl_ap(x) buf_io_get16_fl_apr(&x)
+#define buf_io_get16_fb_ap(x) buf_io_get16_fb_apr(&x)
+
+uint32_t buf_io_get32_fl (uint8_t *buf);
+uint32_t buf_io_get32_fb (uint8_t *buf);
+uint32_t buf_io_get32_fl_apr (uint8_t **buf);
+uint32_t buf_io_get32_fb_apr (uint8_t **buf);
+#define buf_io_get32_fl_ap(x) buf_io_get32_fl_apr(&x)
+#define buf_io_get32_fb_ap(x) buf_io_get32_fb_apr(&x)
+
+uint64_t buf_io_get64_fl (uint8_t *buf);
+uint64_t buf_io_get64_fb (uint8_t *buf);
+uint64_t buf_io_get64_fl_apr (uint8_t **buf);
+uint64_t buf_io_get64_fb_apr (uint8_t **buf);
+#define buf_io_get64_fl_ap(x) buf_io_get64_fl_apr(&x)
+#define buf_io_get64_fb_ap(x) buf_io_get64_fb_apr(&x)
+
+float buf_io_getf_fl (uint8_t *src_ptr);
+float buf_io_getf_fb (uint8_t *src_ptr);
+float buf_io_getf_fl_apr (uint8_t **src_ptr);
+float buf_io_getf_fb_apr (uint8_t **src_ptr);
+#define buf_io_getf_fl_ap(x) buf_io_getf_fl_apr(&x)
+#define buf_io_getf_fb_ap(x) buf_io_getf_fb_apr(&x)
+
+double buf_io_getd_fl (uint8_t *src_ptr);
+double buf_io_getd_fb (uint8_t *src_ptr);
+double buf_io_getd_fl_apr (uint8_t **src_ptr);
+double buf_io_getd_fb_apr (uint8_t **src_ptr);
+#define buf_io_getd_fl_ap(x) buf_io_getd_fl_apr(&x)
+#define buf_io_getd_fb_ap(x) buf_io_getd_fb_apr(&x)
+/** @} */
+
+/**
+ @name endianess dependent functions (PUT)
+ @{
+*/
+void buf_io_put8_tl (uint8_t value, uint8_t *buf);
+void buf_io_put8_tb (uint8_t value, uint8_t *buf);
+void buf_io_put8_tl_apr (uint8_t value, uint8_t **buf);
+void buf_io_put8_tb_apr (uint8_t value, uint8_t **buf);
+#define buf_io_put8_tl_ap(v,x) buf_io_put8_tl_apr(v,&x)
+#define buf_io_put8_tb_ap(v,x) buf_io_put8_tb_apr(v,&x)
+
+void buf_io_put16_tl (uint16_t value, uint8_t *buf);
+void buf_io_put16_tb (uint16_t value, uint8_t *buf);
+void buf_io_put16_tl_apr (uint16_t value, uint8_t **buf);
+void buf_io_put16_tb_apr (uint16_t value, uint8_t **buf);
+#define buf_io_put16_tl_ap(v,x) buf_io_put16_tl_apr(v,&x)
+#define buf_io_put16_tb_ap(v,x) buf_io_put16_tb_apr(v,&x)
+
+void buf_io_put32_tl (uint32_t value, uint8_t *buf);
+void buf_io_put32_tb (uint32_t value, uint8_t *buf);
+void buf_io_put32_tl_apr (uint32_t value, uint8_t **buf);
+void buf_io_put32_tb_apr (uint32_t value, uint8_t **buf);
+#define buf_io_put32_tl_ap(v,x) buf_io_put32_tl_apr(v,&x)
+#define buf_io_put32_tb_ap(v,x) buf_io_put32_tb_apr(v,&x)
+
+void buf_io_put64_tl (uint64_t value, uint8_t *buf);
+void buf_io_put64_tb (uint64_t value, uint8_t *buf);
+void buf_io_put64_tl_apr (uint64_t value, uint8_t **buf);
+void buf_io_put64_tb_apr (uint64_t value, uint8_t **buf);
+#define buf_io_put64_tl_ap(v,x) buf_io_put64_tl_apr(v,&x)
+#define buf_io_put64_tb_ap(v,x) buf_io_put64_tb_apr(v,&x)
+
+void buf_io_putf_tl (float value, uint8_t *buf);
+void buf_io_putf_tb (float value, uint8_t *buf);
+void buf_io_putf_tl_apr (float value, uint8_t **buf);
+void buf_io_putf_tb_apr (float value, uint8_t **buf);
+#define buf_io_putf_tl_ap(v, x) buf_io_putf_tl_apr(v, &x)
+#define buf_io_putf_tb_ap(v, x) buf_io_putf_tb_apr(v, &x)
+
+void buf_io_putd_tl (double value, uint8_t *buf);
+void buf_io_putd_tb (double value, uint8_t *buf);
+void buf_io_putd_tl_apr (double value, uint8_t **buf);
+void buf_io_putd_tb_apr (double value, uint8_t **buf);
+#define buf_io_putd_tl_ap(v, x) buf_io_putd_tl_apr(v, &x)
+#define buf_io_putd_tb_ap(v, x) buf_io_putd_tb_apr(v, &x)
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BUF_IO__ */
diff -r 01c4d4d8febf -r acdf490d94a7 util/crc16.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/crc16.c Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,99 @@
+/*
+ * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
+ * Copyright (c) 2006 Christian Walter <wolti@sil.at>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * File: $Id: mbcrc.c,v 1.7 2007/02/18 23:50:27 wolti Exp $
+ */
+
+/* ----------------------- Platform includes --------------------------------*/
+#include <stdint.h>
+#include "crc16.h"
+
+static const uint8_t crc_hi_table[] = {
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+ 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+ 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
+ 0x00, 0xC1, 0x81, 0x40
+};
+
+static const uint8_t crc_low_table[] = {
+ 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
+ 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
+ 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
+ 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
+ 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
+ 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
+ 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
+ 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
+ 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
+ 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
+ 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
+ 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
+ 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
+ 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
+ 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
+ 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
+ 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
+ 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
+ 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
+ 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
+ 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
+ 0x41, 0x81, 0x80, 0x40
+};
+
+uint16_t crc16_calc(uint8_t * frame, uint16_t len)
+{
+ uint8_t crc_hi = 0xFF;
+ uint8_t crc_low = 0xFF;
+ int iIndex;
+
+ while( len-- )
+ {
+ iIndex = crc_low ^ *( frame++ );
+ crc_low = ( uint8_t )( crc_hi ^ crc_hi_table[iIndex] );
+ crc_hi = crc_low_table[iIndex];
+ }
+
+ return ( uint16_t )( crc_hi << 8 | crc_low );
+}
diff -r 01c4d4d8febf -r acdf490d94a7 util/crc16.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/util/crc16.h Tue Apr 08 16:34:20 2014 +0000
@@ -0,0 +1,35 @@
+/*
+ * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
+ * Copyright (c) 2006 Christian Walter <wolti@sil.at>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ */
+
+#ifndef _MB_CRC_H
+#define _MB_CRC_H
+
+uint16_t crc16_calc(uint8_t *frame, uint16_t len);
+
+#endif