Generic communication interface between the wireless board (mote) and the sensor board. Any kind of sensor board can be connected to the mote using this specification given it provides a SPI peripheral, one input pin with interrupt capability and one digital output. The sensor board must implement a special register set from which all required information can be retrieved. Protocol: http://is.gd/wuQorh Github: http://is.gd/ySj1L9
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