9 #define ASKSIN_PLUS_PLUS_MAJOR 4
10 #define ASKSIN_PLUS_PLUS_MINOR 1
11 #define ASKSIN_PLUS_PLUS_SERVICE 7
13 #define ASKSIN_PLUS_PLUS_VERSION (ASKSIN_PLUS_PLUS_MAJOR * 10000 \
14 + ASKSIN_PLUS_PLUS_MINOR * 100 + ASKSIN_PLUS_PLUS_SERVICE)
16 #define STRINGIZE2(s) #s
17 #define STRINGIZE(s) STRINGIZE2(s)
18 #define ASKSIN_PLUS_PLUS_VERSION_STR STRINGIZE(ASKSIN_PLUS_PLUS_MAJOR) \
19 "." STRINGIZE(ASKSIN_PLUS_PLUS_MINOR) "." STRINGIZE(ASKSIN_PLUS_PLUS_SERVICE)
21 #define ASKSIN_PLUS_PLUS_IDENTIFIER F("AskSin++ V" ASKSIN_PLUS_PLUS_VERSION_STR " (" __DATE__ " " __TIME__ ")")
24 #define CONFIG_FREQ1 0
25 #define CONFIG_FREQ2 1
26 #define CONFIG_BOOTSTATE 2 //location of current boot state for ResetOnBoot
31 #ifdef ARDUINO_ARCH_STM32F1
32 #define _delay_us(us) delayMicroseconds(us)
33 inline void _delay_ms(uint32_t ms) {
do { delayMicroseconds(1000); }
while( (--ms) > 0); }
35 #define NOT_AN_INTERRUPT -1
36 #define digitalPinToInterrupt(pin) (pin)
37 #define enableInterrupt(pin,handler,mode) attachInterrupt(pin,handler,mode)
38 #define disableInterrupt(pin) detachInterrupt(pin)
39 #define memcmp_P(src,dst,count) memcmp((src),(dst),(count))
41 typedef uint8_t uint8;
42 typedef uint16_t uint16;
44 #ifndef EnableInterrupt_h
45 #define enableInterrupt(pin,handler,mode) pinpolling##pin().enable(pin,handler,mode)
46 #define disableInterrupt(pin) pinpolling##pin().disable()
57 #include <AlarmClock.h>
61 #include <BatterySensor.h>
66 extern const char* __gb_chartable;
80 static void pgm_read(uint8_t* dest,uint16_t adr,uint8_t size) {
81 for(
int i=0; i<size; ++i, ++dest ) {
82 *dest = pgm_read_byte(adr + i);
91 return *(__gb_chartable+c);
99 static uint16_t
crc16 (uint16_t crc,uint8_t d) {
101 for( uint8_t i = 8; i != 0; --i ) {
102 crc = (crc >> 1) ^ ((crc & 1) ? 0xA001 : 0 );
113 static uint32_t
crc24(
const uint8_t* data,
int len) {
114 uint32_t crc = 0xB704CEL;
115 for( uint8_t i=0; i<len; ++i) {
116 crc =
crc24(crc,data[i]);
127 static uint32_t
crc24(uint32_t crc,uint8_t d) {
128 crc ^= ((uint32_t)d) << 16;
129 for( uint8_t i = 0; i < 8; i++) {
131 if (crc & 0x1000000) {
135 return crc & 0xFFFFFFL;
139 static uint32_t byteTimeCvt(uint8_t tTime) {
140 if( tTime == 0xff )
return 0xffffffff;
141 const uint16_t c[8] = {1,10,50,100,600,3000,6000,36000};
142 return decis2ticks( (uint32_t)(tTime & 0x1F) * c[tTime >> 5] );
145 static uint32_t byteTimeCvtSeconds (uint8_t tTime) {
146 const uint8_t c[2] = {1,60};
147 return seconds2ticks( (uint32_t)(tTime & 0x7F) * c[tTime >> 7] );
151 static uint32_t intTimeCvt(uint16_t iTime) {
152 if (iTime == 0x00)
return 0x00;
153 if (iTime == 0xffff)
return 0xffffffff;
156 if ((iTime & 0x1F) != 0) {
158 for (uint8_t i = 1; i < (iTime & 0x1F); i++) tByte *= 2;
161 return decis2ticks( (uint32_t)tByte*(iTime>>5) );
170 uint32_t value = ((uint32_t)
id) << 8 | msgcnt;
171 value = (value * 1103515245 + 12345) >> 16;
172 value = (value & 0xFF) + 480;
175 DDEC(value / 1000);DPRINT(
".");DDECLN(value % 1000);
186 static uint8_t
readPin(uint8_t pinnr,uint8_t enablenr=0,uint8_t ms=0) {
188 pinMode(pinnr,INPUT_PULLUP);
189 if( enablenr != 0 ) {
190 digitalWrite(enablenr,HIGH);
195 value = digitalRead(pinnr);
196 pinMode(pinnr,OUTPUT);
197 digitalWrite(pinnr,LOW);
198 if( enablenr != 0 ) {
199 digitalWrite(enablenr,LOW);
206 template <
class StatusLed,
class Battery,
class Radio,
class Buzzer=NoBuzzer>
211 typedef Battery BatteryType;
221 void init (
const HMID&
id) {
222 srand((
unsigned int&)
id);
225 bool ccinitOK = radio.init();
230 led.set(ccinitOK ? LedStates::welcome : LedStates::failure);
232 radio.setSendTimeout((rand() % 3500)+1000);
235 void initBattery(uint16_t interval,uint8_t low,uint8_t critical) {
236 battery.init(seconds2ticks(interval),sysclock);
238 battery.critical(critical);
242 if( sc.valid() ==
true ) {
243 uint8_t f1 = sc.getByte(CONFIG_FREQ1);
244 uint8_t f2 = sc.getByte(CONFIG_FREQ2);
246 if( f1 >= 0x60 && f1 <= 0x6A ) {
247 DPRINT(F(
"Config Freq: 0x21"));DHEX(f1);DHEXLN(f2);
248 radio.initReg(CC1101_FREQ2, 0x21);
249 radio.initReg(CC1101_FREQ1, f1);
250 radio.initReg(CC1101_FREQ0, f2);
256 return sysclock.runready();
261 void prepareSend (__attribute__((unused))
Message& msg) {}
267 void waitTimeout(uint16_t millis) {
268 radio.waitTimeout(millis);
284 #if defined(ARDUINO_ARCH_AVR) && ! ( defined(ARDUINO_AVR_ATmega32) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega128__))
285 template <
bool ENABLETIMER2=false,
bool ENABLEADC=false>
288 template <
bool ENABLETIMER2=false>
291 void sleepForever () { activity.sleepForever(*
this); }
296 template <
class StatusLed,
class Battery,
class Radio,
class Buzzer=NoBuzzer>
299 void init (
const HMID&
id) {
305 void initBattery(uint16_t interval,uint8_t low,uint8_t critical) {
306 this->battery.init(interval,rtc);
307 this->battery.low(low);
308 this->battery.critical(critical);
316 #if defined(ARDUINO_ARCH_AVR) && ! ( defined(ARDUINO_AVR_ATmega32) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega128__))
317 template <
bool ENABLETIMER2=false>
318 void sleep () { this->activity.template savePower< SleepRTC >(*
this); }