Added {} to control structures for clarity (#600)

This commit is contained in:
Thomas Mørch
2016-10-16 12:46:42 +02:00
committed by Olivier
parent 80659ddb00
commit 54776a4520
34 changed files with 740 additions and 406 deletions
+4 -3
View File
@@ -6,7 +6,7 @@
* network topology allowing messages to be routed to nodes. * network topology allowing messages to be routed to nodes.
* *
* Created by Tomas Hozza <thozza@gmail.com> * Created by Tomas Hozza <thozza@gmail.com>
* Copyright (C) 2015 Tomas Hozza * Copyright (C) 2015 Tomas Hozza
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
* *
* Documentation: http://www.mysensors.org * Documentation: http://www.mysensors.org
@@ -135,7 +135,7 @@ bool gatewayTransportInit() {
_w5100_spi_en(false); _w5100_spi_en(false);
return false; return false;
} }
#endif #endif
MY_SERIALDEVICE.print(F("IP: ")); MY_SERIALDEVICE.print(F("IP: "));
MY_SERIALDEVICE.println(Ethernet.localIP()); MY_SERIALDEVICE.println(Ethernet.localIP());
// give the Ethernet interface a second to initialize // give the Ethernet interface a second to initialize
@@ -437,8 +437,9 @@ void gatewayTransportRenewIP()
unsigned long now = hwMillis(); unsigned long now = hwMillis();
// http://playground.arduino.cc/Code/TimingRollover // http://playground.arduino.cc/Code/TimingRollover
if ((long)(now - next_time) < 0) if ((long)(now - next_time) < 0) {
return; return;
}
if (Ethernet.maintain() & ~(0x06)) { if (Ethernet.maintain() & ~(0x06)) {
debug(PSTR("IP was not renewed correctly\n")); debug(PSTR("IP was not renewed correctly\n"));
/* Error occured -> IP was not renewed */ /* Error occured -> IP was not renewed */
+7 -5
View File
@@ -49,8 +49,9 @@ static bool _MQTT_available = false;
static MyMessage _MQTT_msg; static MyMessage _MQTT_msg;
bool gatewayTransportSend(MyMessage &message) { bool gatewayTransportSend(MyMessage &message) {
if (!_MQTT_client.connected()) if (!_MQTT_client.connected()) {
return false; return false;
}
setIndication(INDICATION_GW_TX); setIndication(INDICATION_GW_TX);
char *topic = protocolFormatMQTTTopic(MY_MQTT_PUBLISH_TOPIC_PREFIX, message); char *topic = protocolFormatMQTTTopic(MY_MQTT_PUBLISH_TOPIC_PREFIX, message);
debug(PSTR("Sending message on topic: %s\n"), topic); debug(PSTR("Sending message on topic: %s\n"), topic);
@@ -134,7 +135,7 @@ bool gatewayTransportInit() {
(void)WiFi.begin(MY_ESP8266_SSID, MY_ESP8266_PASSWORD); (void)WiFi.begin(MY_ESP8266_SSID, MY_ESP8266_PASSWORD);
#ifdef MY_IP_ADDRESS #ifdef MY_IP_ADDRESS
WiFi.config(_MQTT_clientIp, _gatewayIp, _subnetIp); WiFi.config(_MQTT_clientIp, _gatewayIp, _subnetIp);
#endif #endif
#endif #endif
gatewayTransportConnect(); gatewayTransportConnect();
@@ -144,15 +145,16 @@ bool gatewayTransportInit() {
} }
bool gatewayTransportAvailable() { bool gatewayTransportAvailable() {
if (_MQTT_connecting) if (_MQTT_connecting) {
return false; return false;
}
//keep lease on dhcp address //keep lease on dhcp address
//Ethernet.maintain(); //Ethernet.maintain();
if (!_MQTT_client.connected()) { if (!_MQTT_client.connected()) {
//reinitialise client //reinitialise client
if (gatewayTransportConnect()) if (gatewayTransportConnect()) {
reconnectMQTT(); reconnectMQTT();
}
return false; return false;
} }
_MQTT_client.loop(); _MQTT_client.loop();
+32 -23
View File
@@ -81,7 +81,7 @@ void hwPowerDown(period_t period) {
sei(); sei();
// Directly sleep CPU, to prevent race conditions! (see chapter 7.7 of ATMega328P datasheet) // Directly sleep CPU, to prevent race conditions! (see chapter 7.7 of ATMega328P datasheet)
sleep_cpu(); sleep_cpu();
sleep_disable(); sleep_disable();
// restore previous WDT settings // restore previous WDT settings
cli(); cli();
wdt_reset(); wdt_reset();
@@ -124,12 +124,16 @@ int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mo
// Disable interrupts until going to sleep, otherwise interrupts occurring between attachInterrupt() // Disable interrupts until going to sleep, otherwise interrupts occurring between attachInterrupt()
// and sleep might cause the ATMega to not wakeup from sleep as interrupt has already be handled! // and sleep might cause the ATMega to not wakeup from sleep as interrupt has already be handled!
cli(); cli();
// attach interrupts // attach interrupts
_wakeUp1Interrupt = interrupt1; _wakeUp1Interrupt = interrupt1;
_wakeUp2Interrupt = interrupt2; _wakeUp2Interrupt = interrupt2;
if (interrupt1 != INVALID_INTERRUPT_NUM) attachInterrupt(interrupt1, wakeUp1, mode1); if (interrupt1 != INVALID_INTERRUPT_NUM) {
if (interrupt2 != INVALID_INTERRUPT_NUM) attachInterrupt(interrupt2, wakeUp2, mode2); attachInterrupt(interrupt1, wakeUp1, mode1);
}
if (interrupt2 != INVALID_INTERRUPT_NUM) {
attachInterrupt(interrupt2, wakeUp2, mode2);
}
if (ms>0) { if (ms>0) {
// sleep for defined time // sleep for defined time
hwInternalSleep(ms); hwInternalSleep(ms);
@@ -137,15 +141,20 @@ int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mo
// sleep until ext interrupt triggered // sleep until ext interrupt triggered
hwPowerDown(SLEEP_FOREVER); hwPowerDown(SLEEP_FOREVER);
} }
// Assure any interrupts attached, will get detached when they did not occur. // Assure any interrupts attached, will get detached when they did not occur.
if (interrupt1 != INVALID_INTERRUPT_NUM) detachInterrupt(interrupt1); if (interrupt1 != INVALID_INTERRUPT_NUM) {
if (interrupt2 != INVALID_INTERRUPT_NUM) detachInterrupt(interrupt2); detachInterrupt(interrupt1);
}
if (interrupt2 != INVALID_INTERRUPT_NUM) {
detachInterrupt(interrupt2);
}
// Return what woke the mcu. // Return what woke the mcu.
int8_t ret = MY_WAKE_UP_BY_TIMER; // default: no interrupt triggered, timer wake up int8_t ret = MY_WAKE_UP_BY_TIMER; // default: no interrupt triggered, timer wake up
if (interruptWakeUp()) ret = static_cast<int8_t>(_wokeUpByInterrupt); if (interruptWakeUp()) {
ret = static_cast<int8_t>(_wokeUpByInterrupt);
}
// Clear woke-up-by-interrupt flag, so next sleeps won't return immediately. // Clear woke-up-by-interrupt flag, so next sleeps won't return immediately.
_wokeUpByInterrupt = INVALID_INTERRUPT_NUM; _wokeUpByInterrupt = INVALID_INTERRUPT_NUM;
@@ -153,7 +162,7 @@ int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mo
} }
uint16_t hwCPUVoltage() { uint16_t hwCPUVoltage() {
// Measure Vcc against 1.1V Vref // Measure Vcc against 1.1V Vref
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = (_BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1)); ADMUX = (_BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1));
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
@@ -162,12 +171,12 @@ uint16_t hwCPUVoltage() {
ADMUX = (_BV(MUX3) | _BV(MUX2)); ADMUX = (_BV(MUX3) | _BV(MUX2));
#else #else
ADMUX = (_BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1)); ADMUX = (_BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1));
#endif #endif
// Vref settle // Vref settle
delay(70); delay(70);
// Do conversion // Do conversion
ADCSRA |= _BV(ADSC); ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA,ADSC)); while (bit_is_set(ADCSRA,ADSC)) {};
// return Vcc in mV // return Vcc in mV
return (1125300UL) / ADC; return (1125300UL) / ADC;
} }
@@ -175,8 +184,8 @@ uint16_t hwCPUVoltage() {
uint16_t hwCPUFrequency() { uint16_t hwCPUFrequency() {
cli(); cli();
// setup timer1 // setup timer1
TIFR1 = 0xFF; TIFR1 = 0xFF;
TCNT1 = 0; TCNT1 = 0;
TCCR1A = 0; TCCR1A = 0;
TCCR1C = 0; TCCR1C = 0;
// save WDT settings // save WDT settings
@@ -186,24 +195,24 @@ uint16_t hwCPUFrequency() {
WDTCSR |= (1 << WDIE); WDTCSR |= (1 << WDIE);
wdt_reset(); wdt_reset();
// start timer1 with 1024 prescaling // start timer1 with 1024 prescaling
TCCR1B = _BV(CS12) | _BV(CS10); TCCR1B = _BV(CS12) | _BV(CS10);
// wait until wdt interrupt // wait until wdt interrupt
while (bit_is_clear(WDTCSR,WDIF)); while (bit_is_clear(WDTCSR,WDIF)) {};
// stop timer // stop timer
TCCR1B = 0; TCCR1B = 0;
// restore WDT settings // restore WDT settings
wdt_reset(); wdt_reset();
WDTCSR |= (1 << WDCE) | (1 << WDE); WDTCSR |= (1 << WDCE) | (1 << WDE);
WDTCSR = WDTsave; WDTCSR = WDTsave;
sei(); sei();
// return frequency in 1/10MHz (accuracy +- 10%) // return frequency in 1/10MHz (accuracy +- 10%)
return TCNT1 * 2048UL / 100000UL; return TCNT1 * 2048UL / 100000UL;
} }
uint16_t hwFreeMem() { uint16_t hwFreeMem() {
extern int __heap_start, *__brkval; extern int __heap_start, *__brkval;
int v; int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
} }
+3 -1
View File
@@ -58,7 +58,9 @@ byte i2c_eeprom_read_byte(unsigned int eeaddress ) {
Wire.write((int)(eeaddress & 0xFF)); // LSB Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission(); Wire.endTransmission();
Wire.requestFrom(I2C_EEP_ADDRESS,1); Wire.requestFrom(I2C_EEP_ADDRESS,1);
if (Wire.available()) rdata = Wire.read(); if (Wire.available()) {
rdata = Wire.read();
}
return rdata; return rdata;
} }
+3 -2
View File
@@ -43,6 +43,7 @@ void setIndication( const indication_t ind )
ledsBlinkErr(ind-INDICATION_ERR_START); ledsBlinkErr(ind-INDICATION_ERR_START);
} }
#endif #endif
if (indication) if (indication) {
indication(ind); indication(ind);
}
} }
+11 -4
View File
@@ -51,8 +51,9 @@ inline void ledsInit()
void ledsProcess() { void ledsProcess() {
// Just return if it is not the time... // Just return if it is not the time...
if ((hwMillis() - prevTime) < LED_PROCESS_INTERVAL_MS) if ((hwMillis() - prevTime) < LED_PROCESS_INTERVAL_MS) {
return; return;
}
prevTime += LED_PROCESS_INTERVAL_MS; prevTime += LED_PROCESS_INTERVAL_MS;
@@ -63,19 +64,25 @@ void ledsProcess() {
#if defined(MY_DEFAULT_RX_LED_PIN) #if defined(MY_DEFAULT_RX_LED_PIN)
state = (countRx & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF; state = (countRx & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF;
hwDigitalWrite(MY_DEFAULT_RX_LED_PIN, state); hwDigitalWrite(MY_DEFAULT_RX_LED_PIN, state);
if (countRx) --countRx; if (countRx) {
--countRx;
}
#endif #endif
#if defined(MY_DEFAULT_TX_LED_PIN) #if defined(MY_DEFAULT_TX_LED_PIN)
state = (countTx & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF; state = (countTx & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF;
hwDigitalWrite(MY_DEFAULT_TX_LED_PIN, state); hwDigitalWrite(MY_DEFAULT_TX_LED_PIN, state);
if (countTx) --countTx; if (countTx) {
--countTx;
}
#endif #endif
#if defined(MY_DEFAULT_ERR_LED_PIN) #if defined(MY_DEFAULT_ERR_LED_PIN)
state = (countErr & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF; state = (countErr & (LED_ON_OFF_RATIO-1)) ? LED_ON : LED_OFF;
hwDigitalWrite(MY_DEFAULT_ERR_LED_PIN, state); hwDigitalWrite(MY_DEFAULT_ERR_LED_PIN, state);
if (countErr) --countErr; if (countErr) {
--countErr;
}
#endif #endif
} }
+25 -2
View File
@@ -1,3 +1,22 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
// Initialize library and handle sketch functions like we want to // Initialize library and handle sketch functions like we want to
int main(void) { int main(void) {
@@ -12,8 +31,12 @@ int main(void) {
for(;;) { for(;;) {
_process(); // Process incoming data _process(); // Process incoming data
if (loop) loop(); // Call sketch loop if (loop) {
if (serialEventRun) serialEventRun(); loop(); // Call sketch loop
}
if (serialEventRun) {
serialEventRun();
}
} }
return 0; return 0;
} }
+22 -3
View File
@@ -1,4 +1,22 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
//This may be used to change user task stack size: //This may be used to change user task stack size:
//#define CONT_STACKSIZE 4096 //#define CONT_STACKSIZE 4096
#include "Schedule.h" #include "Schedule.h"
@@ -109,8 +127,9 @@ static void loop_task(os_event_t *events) {
static void do_global_ctors(void) { static void do_global_ctors(void) {
void(**p)(void) = &__init_array_end; void(**p)(void) = &__init_array_end;
while (p != &__init_array_start) while (p != &__init_array_start) {
(*--p)(); (*--p)();
}
} }
extern "C" void __gdb_init() {} extern "C" void __gdb_init() {}
@@ -144,4 +163,4 @@ extern "C" void user_init(void) {
LOOP_QUEUE_SIZE); LOOP_QUEUE_SIZE);
system_init_done_cb(&init_done); system_init_done_cb(&init_done);
} }
+22 -2
View File
@@ -1,4 +1,22 @@
// Initialize library and handle sketch functions like we want to /**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
// Initialize library and handle sketch functions like we want to
#include <stdio.h> #include <stdio.h>
#include <csignal> #include <csignal>
@@ -129,7 +147,9 @@ int main(int argc, char *argv[])
for (;;) { for (;;) {
_process(); // Process incoming data _process(); // Process incoming data
if (loop) loop(); // Call sketch loop if (loop) {
loop(); // Call sketch loop
}
} }
return 0; return 0;
} }
+8 -6
View File
@@ -75,10 +75,12 @@ const char* MyMessage::getString() const {
// handles single character hex (0 - 15) // handles single character hex (0 - 15)
char MyMessage::i2h(uint8_t i) const { char MyMessage::i2h(uint8_t i) const {
uint8_t k = i & 0x0F; uint8_t k = i & 0x0F;
if (k <= 9) if (k <= 9) {
return '0' + k; return '0' + k;
else }
else {
return 'A' + k - 10; return 'A' + k - 10;
}
} }
char* MyMessage::getCustomString(char *buffer) const { char* MyMessage::getCustomString(char *buffer) const {
@@ -173,7 +175,7 @@ uint32_t MyMessage::getULong() const {
} }
int16_t MyMessage::getInt() const { int16_t MyMessage::getInt() const {
if (miGetPayloadType() == P_INT16) { if (miGetPayloadType() == P_INT16) {
return iValue; return iValue;
} else if (miGetPayloadType() == P_STRING) { } else if (miGetPayloadType() == P_STRING) {
return atoi(data); return atoi(data);
@@ -183,7 +185,7 @@ int16_t MyMessage::getInt() const {
} }
uint16_t MyMessage::getUInt() const { uint16_t MyMessage::getUInt() const {
if (miGetPayloadType() == P_UINT16) { if (miGetPayloadType() == P_UINT16) {
return uiValue; return uiValue;
} else if (miGetPayloadType() == P_STRING) { } else if (miGetPayloadType() == P_STRING) {
return atoi(data); return atoi(data);
@@ -211,7 +213,7 @@ MyMessage& MyMessage::setDestination(uint8_t _destination) {
// Set payload // Set payload
MyMessage& MyMessage::set(void* value, uint8_t length) { MyMessage& MyMessage::set(void* value, uint8_t length) {
uint8_t payloadLength = value == NULL ? 0 : min(length, (uint8_t)MAX_PAYLOAD); uint8_t payloadLength = value == NULL ? 0 : min(length, (uint8_t)MAX_PAYLOAD);
miSetLength(payloadLength); miSetLength(payloadLength);
miSetPayloadType(P_CUSTOM); miSetPayloadType(P_CUSTOM);
memcpy(data, value, payloadLength); memcpy(data, value, payloadLength);
return *this; return *this;
@@ -221,7 +223,7 @@ MyMessage& MyMessage::set(const char* value) {
uint8_t length = value == NULL ? 0 : min(strlen(value), (size_t)MAX_PAYLOAD); uint8_t length = value == NULL ? 0 : min(strlen(value), (size_t)MAX_PAYLOAD);
miSetLength(length); miSetLength(length);
miSetPayloadType(P_STRING); miSetPayloadType(P_STRING);
if (length) { if (length) {
strncpy(data, value, length); strncpy(data, value, length);
} }
// null terminate string // null terminate string
+10 -8
View File
@@ -16,7 +16,7 @@
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation. * version 2 as published by the Free Software Foundation.
*/ */
#include "MyOTAFirmwareUpdate.h" #include "MyOTAFirmwareUpdate.h"
// global variables // global variables
@@ -76,7 +76,7 @@ bool firmwareOTAUpdateProcess() {
// erase lower 32K -> max flash size for ATMEGA328 // erase lower 32K -> max flash size for ATMEGA328
_flash.blockErase32K(0); _flash.blockErase32K(0);
// wait until flash erased // wait until flash erased
while ( _flash.busy() ); while ( _flash.busy() ) {}
_fwBlock = _fc.blocks; _fwBlock = _fc.blocks;
_fwUpdateOngoing = true; _fwUpdateOngoing = true;
// reset flags // reset flags
@@ -96,7 +96,7 @@ bool firmwareOTAUpdateProcess() {
// write to flash // write to flash
_flash.writeBytes( ((_fwBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET, firmwareResponse->data, FIRMWARE_BLOCK_SIZE); _flash.writeBytes( ((_fwBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET, firmwareResponse->data, FIRMWARE_BLOCK_SIZE);
// wait until flash written // wait until flash written
while ( _flash.busy() ); while ( _flash.busy() ) {}
_fwBlock--; _fwBlock--;
if (!_fwBlock) { if (!_fwBlock) {
// We're finished! Do a checksum and reboot. // We're finished! Do a checksum and reboot.
@@ -137,7 +137,7 @@ void presentBootloaderInformation(){
// add bootloader information // add bootloader information
reqFWConfig->BLVersion = MY_OTA_BOOTLOADER_VERSION; reqFWConfig->BLVersion = MY_OTA_BOOTLOADER_VERSION;
_fwUpdateOngoing = false; _fwUpdateOngoing = false;
_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_STREAM, ST_FIRMWARE_CONFIG_REQUEST, false)); _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_STREAM, ST_FIRMWARE_CONFIG_REQUEST, false));
} }
// do a crc16 on the whole received firmware // do a crc16 on the whole received firmware
bool transportIsValidFirmware() { bool transportIsValidFirmware() {
@@ -146,10 +146,12 @@ bool transportIsValidFirmware() {
for (uint16_t i = 0; i < _fc.blocks * FIRMWARE_BLOCK_SIZE; ++i) { for (uint16_t i = 0; i < _fc.blocks * FIRMWARE_BLOCK_SIZE; ++i) {
crc ^= _flash.readByte(i + FIRMWARE_START_OFFSET); crc ^= _flash.readByte(i + FIRMWARE_START_OFFSET);
for (int8_t j = 0; j < 8; ++j) { for (int8_t j = 0; j < 8; ++j) {
if (crc & 1) if (crc & 1) {
crc = (crc >> 1) ^ 0xA001; crc = (crc >> 1) ^ 0xA001;
else }
crc = (crc >> 1); else {
crc = (crc >> 1);
}
} }
} }
return crc == _fc.crc; return crc == _fc.crc;
+3 -3
View File
@@ -36,7 +36,7 @@
* *
* |E| SYS | SUB | Message | Comment * |E| SYS | SUB | Message | Comment
* |-|------|-------|-------------------------------------------|---------------------------------------------------------------------------- * |-|------|-------|-------------------------------------------|----------------------------------------------------------------------------
* | | OTA | FWP | UPDATE | FW update initiated * | | OTA | FWP | UPDATE | FW update initiated
* |!| OTA | FWP | FLASH INIT FAIL | Failed to initialise flash * |!| OTA | FWP | FLASH INIT FAIL | Failed to initialise flash
* | | OTA | FWP | UPDATE SKIPPED | FW update skipped, no newer version available * | | OTA | FWP | UPDATE SKIPPED | FW update skipped, no newer version available
* | | OTA | FWP | RECV B=%04X | Received FW block (B) * | | OTA | FWP | RECV B=%04X | Received FW block (B)
@@ -132,10 +132,10 @@ bool firmwareOTAUpdateProcess();
*/ */
bool transportIsValidFirmware(); bool transportIsValidFirmware();
/** /**
* @brief Present bootloader/FW information upon startup * @brief Present bootloader/FW information upon startup
*/ */
void presentBootloaderInformation(); void presentBootloaderInformation();
#endif #endif
/** @}*/ /** @}*/
+18 -10
View File
@@ -70,10 +70,12 @@ bool protocolParse(MyMessage &message, char *inputString) {
value = str; value = str;
// Remove trailing carriage return and newline character (if it exists) // Remove trailing carriage return and newline character (if it exists)
uint8_t lastCharacter = strlen(value)-1; uint8_t lastCharacter = strlen(value)-1;
if (value[lastCharacter] == '\r') if (value[lastCharacter] == '\r') {
value[lastCharacter] = 0; value[lastCharacter] = 0;
if (value[lastCharacter] == '\n') }
if (value[lastCharacter] == '\n') {
value[lastCharacter] = 0; value[lastCharacter] = 0;
}
} }
break; break;
} }
@@ -81,16 +83,18 @@ bool protocolParse(MyMessage &message, char *inputString) {
} }
//debug(PSTR("Received %d"), i); //debug(PSTR("Received %d"), i);
// Check for invalid input // Check for invalid input
if (i < 5) if (i < 5) {
return false; return false;
}
message.sender = GATEWAY_ADDRESS; message.sender = GATEWAY_ADDRESS;
message.last = GATEWAY_ADDRESS; message.last = GATEWAY_ADDRESS;
mSetAck(message, false); mSetAck(message, false);
if (command == C_STREAM) if (command == C_STREAM) {
message.set(bvalue, blen); message.set(bvalue, blen);
else }
else {
message.set(value); message.set(value);
}
return true; return true;
} }
@@ -158,8 +162,9 @@ bool protocolMQTTParse(MyMessage &message, char* topic, uint8_t* payload, unsign
i++; i++;
} }
if (i != 6) if (i != 6) {
return false; return false;
}
message.sender = GATEWAY_ADDRESS; message.sender = GATEWAY_ADDRESS;
message.last = GATEWAY_ADDRESS; message.last = GATEWAY_ADDRESS;
@@ -190,11 +195,14 @@ bool protocolMQTTParse(MyMessage &message, char* topic, uint8_t* payload, unsign
uint8_t protocolH2i(char c) { uint8_t protocolH2i(char c) {
uint8_t i = 0; uint8_t i = 0;
if (c <= '9') if (c <= '9') {
i += c - '0'; i += c - '0';
else if (c >= 'a') }
else if (c >= 'a') {
i += c - 'a' + 10; i += c - 'a' + 10;
else }
else {
i += c - 'A' + 10; i += c - 'A' + 10;
}
return i; return i;
} }
+17 -9
View File
@@ -72,8 +72,9 @@ void _infiniteLoop(void) {
void _begin(void) { void _begin(void) {
hwWatchdogReset(); hwWatchdogReset();
if (preHwInit) if (preHwInit) {
preHwInit(); preHwInit();
}
hwInit(); hwInit();
@@ -120,7 +121,7 @@ void _begin(void) {
pinMode(MY_NODE_UNLOCK_PIN, INPUT_PULLUP); pinMode(MY_NODE_UNLOCK_PIN, INPUT_PULLUP);
// Make a short delay so we are sure any large external nets are fully pulled // Make a short delay so we are sure any large external nets are fully pulled
unsigned long enter = hwMillis(); unsigned long enter = hwMillis();
while (hwMillis() - enter < 2); while (hwMillis() - enter < 2) {}
if (digitalRead(MY_NODE_UNLOCK_PIN) == 0) { if (digitalRead(MY_NODE_UNLOCK_PIN) == 0) {
// Pin is grounded, reset lock counter // Pin is grounded, reset lock counter
hwWriteConfig(EEPROM_NODE_LOCK_COUNTER, MY_NODE_LOCK_COUNTER_MAX); hwWriteConfig(EEPROM_NODE_LOCK_COUNTER, MY_NODE_LOCK_COUNTER_MAX);
@@ -224,9 +225,9 @@ void presentNode(void) {
#endif #endif
if (presentation) if (presentation) {
presentation(); presentation();
}
} }
@@ -299,8 +300,12 @@ bool present(const uint8_t childSensorId, const uint8_t sensorType, const char *
bool sendSketchInfo(const char *name, const char *version, const bool ack) { bool sendSketchInfo(const char *name, const char *version, const bool ack) {
bool result = true; bool result = true;
if (name) result &= _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_NAME, ack).set(name)); if (name) {
if (version) result &= _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_VERSION, ack).set(version)); result &= _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_NAME, ack).set(name));
}
if (version) {
result &= _sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_VERSION, ack).set(version));
}
return result; return result;
} }
@@ -345,8 +350,9 @@ bool _processInternalMessages(void) {
} }
else if (type == I_TIME) { else if (type == I_TIME) {
// Deliver time to callback // Deliver time to callback
if (receiveTime) if (receiveTime) {
receiveTime(_msg.getULong()); receiveTime(_msg.getULong());
}
} }
else if (type == I_CHILDREN) { else if (type == I_CHILDREN) {
#if defined(MY_REPEATER_FEATURE) #if defined(MY_REPEATER_FEATURE)
@@ -385,7 +391,9 @@ bool _processInternalMessages(void) {
} }
else if (debug_msg == 'E') { // clear MySensors eeprom area and reboot else if (debug_msg == 'E') { // clear MySensors eeprom area and reboot
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_DEBUG).set("OK")); (void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_DEBUG).set("OK"));
for (int i = EEPROM_START; i<EEPROM_LOCAL_CONFIG_ADDRESS; i++) hwWriteConfig(i, 0xFF); for (int i = EEPROM_START; i<EEPROM_LOCAL_CONFIG_ADDRESS; i++) {
hwWriteConfig(i, 0xFF);
}
setIndication(INDICATION_REBOOT); setIndication(INDICATION_REBOOT);
hwReboot(); hwReboot();
} }
@@ -405,7 +413,7 @@ bool _processInternalMessages(void) {
#if defined(MY_CORE_COMPATIBILITY_CHECK) #if defined(MY_CORE_COMPATIBILITY_CHECK)
approveRegistration = (_msg.getByte() >= MY_CORE_MIN_VERSION); approveRegistration = (_msg.getByte() >= MY_CORE_MIN_VERSION);
#endif #endif
#if (F_CPU>16000000) #if (F_CPU>16000000)
// delay for fast GW and slow nodes // delay for fast GW and slow nodes
delay(5); delay(5);
+13 -9
View File
@@ -52,10 +52,12 @@ static uint8_t* signerSha256(const uint8_t* data, size_t sz);
static char i2h(uint8_t i) static char i2h(uint8_t i)
{ {
uint8_t k = i & 0x0F; uint8_t k = i & 0x0F;
if (k <= 9) if (k <= 9) {
return '0' + k; return '0' + k;
else }
else {
return 'A' + k - 10; return 'A' + k - 10;
}
} }
static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, uint8_t sz) { static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, uint8_t sz) {
@@ -98,7 +100,7 @@ bool signerAtsha204CheckTimer(void) {
memset(_signing_signing_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH); memset(_signing_signing_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH);
memset(_signing_verifying_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH); memset(_signing_verifying_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH);
_signing_verification_ongoing = false; _signing_verification_ongoing = false;
return false; return false;
} }
} }
return true; return true;
@@ -132,7 +134,9 @@ bool signerAtsha204GetNonce(MyMessage &msg) {
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover) // Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
// Note that if message is "too" quick, and arrives before turnover, it will be rejected // Note that if message is "too" quick, and arrives before turnover, it will be rejected
// but this is consider such a rare case that it is accepted and rejects are 'safe' // but this is consider such a rare case that it is accepted and rejects are 'safe'
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) _signing_timestamp = 0; if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) {
_signing_timestamp = 0;
}
return true; return true;
} }
@@ -148,7 +152,7 @@ bool signerAtsha204SignMsg(MyMessage &msg) {
// If we cannot fit any signature in the message, refuse to sign it // If we cannot fit any signature in the message, refuse to sign it
if (mGetLength(msg) > MAX_PAYLOAD-2) { if (mGetLength(msg) > MAX_PAYLOAD-2) {
DEBUG_SIGNING_PRINTBUF(F("Message too large"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Message too large"), NULL, 0);
return false; return false;
} }
// Calculate signature of message // Calculate signature of message
@@ -180,18 +184,18 @@ bool signerAtsha204SignMsg(MyMessage &msg) {
bool signerAtsha204VerifyMsg(MyMessage &msg) { bool signerAtsha204VerifyMsg(MyMessage &msg) {
if (!_signing_verification_ongoing) { if (!_signing_verification_ongoing) {
DEBUG_SIGNING_PRINTBUF(F("No active verification session"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("No active verification session"), NULL, 0);
return false; return false;
} else { } else {
// Make sure we have not expired // Make sure we have not expired
if (!signerCheckTimer()) { if (!signerCheckTimer()) {
return false; return false;
} }
_signing_verification_ongoing = false; _signing_verification_ongoing = false;
if (msg.data[mGetLength(msg)] != SIGNING_IDENTIFIER) { if (msg.data[mGetLength(msg)] != SIGNING_IDENTIFIER) {
DEBUG_SIGNING_PRINTBUF(F("Incorrect signing identifier"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Incorrect signing identifier"), NULL, 0);
return false; return false;
} }
DEBUG_SIGNING_PRINTBUF(F("Signature in message: "), (uint8_t*)&msg.data[mGetLength(msg)], MAX_PAYLOAD-mGetLength(msg)); DEBUG_SIGNING_PRINTBUF(F("Signature in message: "), (uint8_t*)&msg.data[mGetLength(msg)], MAX_PAYLOAD-mGetLength(msg));
@@ -230,7 +234,7 @@ bool signerAtsha204VerifyMsg(MyMessage &msg) {
#ifdef MY_SIGNING_NODE_WHITELISTING #ifdef MY_SIGNING_NODE_WHITELISTING
DEBUG_SIGNING_PRINTBUF(F("Is the sender whitelisted and serial correct?"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Is the sender whitelisted and serial correct?"), NULL, 0);
#endif #endif
return false; return false;
} else { } else {
DEBUG_SIGNING_PRINTBUF(F("Signature OK"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Signature OK"), NULL, 0);
return true; return true;
+50 -22
View File
@@ -56,10 +56,12 @@ static void signerCalculateSignature(MyMessage &msg, bool signing);
static char i2h(uint8_t i) static char i2h(uint8_t i)
{ {
uint8_t k = i & 0x0F; uint8_t k = i & 0x0F;
if (k <= 9) if (k <= 9) {
return '0' + k; return '0' + k;
else }
else {
return 'A' + k - 10; return 'A' + k - 10;
}
} }
static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, uint8_t sz) { static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, uint8_t sz) {
@@ -106,7 +108,7 @@ bool signerAtsha204SoftCheckTimer(void) {
memset(_signing_signing_nonce, 0xAA, 32); memset(_signing_signing_nonce, 0xAA, 32);
memset(_signing_verifying_nonce, 0xAA, 32); memset(_signing_verifying_nonce, 0xAA, 32);
_signing_verification_ongoing = false; _signing_verification_ongoing = false;
return false; return false;
} }
} }
return true; return true;
@@ -115,7 +117,7 @@ bool signerAtsha204SoftCheckTimer(void) {
bool signerAtsha204SoftGetNonce(MyMessage &msg) { bool signerAtsha204SoftGetNonce(MyMessage &msg) {
DEBUG_SIGNING_PRINTBUF(F("Signing backend: ATSHA204Soft"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Signing backend: ATSHA204Soft"), NULL, 0);
// We used a basic whitening technique that XORs a random byte with the current hwMillis() counter and then the byte is // We used a basic whitening technique that XORs a random byte with the current hwMillis() counter and then the byte is
// hashed (SHA256) to produce the resulting nonce // hashed (SHA256) to produce the resulting nonce
_signing_sha256.init(); _signing_sha256.init();
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
@@ -134,7 +136,9 @@ bool signerAtsha204SoftGetNonce(MyMessage &msg) {
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover) // Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
// Note that if message is "too" quick, and arrives before turnover, it will be rejected // Note that if message is "too" quick, and arrives before turnover, it will be rejected
// but this is consider such a rare case that it is accepted and rejects are 'safe' // but this is consider such a rare case that it is accepted and rejects are 'safe'
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) _signing_timestamp = 0; if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < hwMillis()) {
_signing_timestamp = 0;
}
return true; return true;
} }
@@ -150,7 +154,7 @@ bool signerAtsha204SoftSignMsg(MyMessage &msg) {
// If we cannot fit any signature in the message, refuse to sign it // If we cannot fit any signature in the message, refuse to sign it
if (mGetLength(msg) > MAX_PAYLOAD-2) { if (mGetLength(msg) > MAX_PAYLOAD-2) {
DEBUG_SIGNING_PRINTBUF(F("Message too large"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Message too large"), NULL, 0);
return false; return false;
} }
// Calculate signature of message // Calculate signature of message
@@ -160,9 +164,13 @@ bool signerAtsha204SoftSignMsg(MyMessage &msg) {
if (DO_WHITELIST(msg.destination)) { if (DO_WHITELIST(msg.destination)) {
// Salt the signature with the senders nodeId and the (hopefully) unique serial The Creator has provided // Salt the signature with the senders nodeId and the (hopefully) unique serial The Creator has provided
_signing_sha256.init(); _signing_sha256.init();
for (int i=0; i<32; i++) _signing_sha256.write(_signing_hmac[i]); for (int i=0; i<32; i++) {
_signing_sha256.write(_signing_hmac[i]);
}
_signing_sha256.write(msg.sender); _signing_sha256.write(msg.sender);
for (int i=0; i<SHA204_SERIAL_SZ; i++) _signing_sha256.write(_signing_node_serial_info[i]); for (int i=0; i<SHA204_SERIAL_SZ; i++) {
_signing_sha256.write(_signing_node_serial_info[i]);
}
memcpy(_signing_hmac, _signing_sha256.result(), 32); memcpy(_signing_hmac, _signing_sha256.result(), 32);
DEBUG_SIGNING_PRINTBUF(F("SHA256: "), _signing_hmac, 32); DEBUG_SIGNING_PRINTBUF(F("SHA256: "), _signing_hmac, 32);
DEBUG_SIGNING_PRINTBUF(F("Signature salted with serial"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Signature salted with serial"), NULL, 0);
@@ -181,18 +189,18 @@ bool signerAtsha204SoftSignMsg(MyMessage &msg) {
bool signerAtsha204SoftVerifyMsg(MyMessage &msg) { bool signerAtsha204SoftVerifyMsg(MyMessage &msg) {
if (!_signing_verification_ongoing) { if (!_signing_verification_ongoing) {
DEBUG_SIGNING_PRINTBUF(F("No active verification session"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("No active verification session"), NULL, 0);
return false; return false;
} else { } else {
// Make sure we have not expired // Make sure we have not expired
if (!signerCheckTimer()) { if (!signerCheckTimer()) {
return false; return false;
} }
_signing_verification_ongoing = false; _signing_verification_ongoing = false;
if (msg.data[mGetLength(msg)] != SIGNING_IDENTIFIER) { if (msg.data[mGetLength(msg)] != SIGNING_IDENTIFIER) {
DEBUG_SIGNING_PRINTBUF(F("Incorrect signing identifier"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Incorrect signing identifier"), NULL, 0);
return false; return false;
} }
// Get signature of message // Get signature of message
@@ -206,9 +214,13 @@ bool signerAtsha204SoftVerifyMsg(MyMessage &msg) {
if (_signing_whitelist[j].nodeId == msg.sender) { if (_signing_whitelist[j].nodeId == msg.sender) {
DEBUG_SIGNING_PRINTBUF(F("Sender found in whitelist"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Sender found in whitelist"), NULL, 0);
_signing_sha256.init(); _signing_sha256.init();
for (int i=0; i<32; i++) _signing_sha256.write(_signing_hmac[i]); for (int i=0; i<32; i++) {
_signing_sha256.write(_signing_hmac[i]);
}
_signing_sha256.write(msg.sender); _signing_sha256.write(msg.sender);
for (int i=0; i<SHA204_SERIAL_SZ; i++) _signing_sha256.write(_signing_whitelist[j].serial[i]); for (int i=0; i<SHA204_SERIAL_SZ; i++) {
_signing_sha256.write(_signing_whitelist[j].serial[i]);
}
memcpy(_signing_hmac, _signing_sha256.result(), 32); memcpy(_signing_hmac, _signing_sha256.result(), 32);
DEBUG_SIGNING_PRINTBUF(F("SHA256: "), _signing_hmac, 32); DEBUG_SIGNING_PRINTBUF(F("SHA256: "), _signing_hmac, 32);
break; break;
@@ -229,7 +241,7 @@ bool signerAtsha204SoftVerifyMsg(MyMessage &msg) {
#ifdef MY_SIGNING_NODE_WHITELISTING #ifdef MY_SIGNING_NODE_WHITELISTING
DEBUG_SIGNING_PRINTBUF(F("Is the sender whitelisted and serial correct?"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Is the sender whitelisted and serial correct?"), NULL, 0);
#endif #endif
return false; return false;
} else { } else {
DEBUG_SIGNING_PRINTBUF(F("Signature OK"), NULL, 0); DEBUG_SIGNING_PRINTBUF(F("Signature OK"), NULL, 0);
return true; return true;
@@ -268,7 +280,9 @@ static void signerCalculateSignature(MyMessage &msg, bool signing) {
// Calculate message digest first // Calculate message digest first
_signing_sha256.init(); _signing_sha256.init();
for (int i=0; i<32; i++) _signing_sha256.write(_signing_temp_message[i]); for (int i=0; i<32; i++) {
_signing_sha256.write(_signing_temp_message[i]);
}
_signing_sha256.write(0x15); // OPCODE _signing_sha256.write(0x15); // OPCODE
_signing_sha256.write(0x02); // param1 _signing_sha256.write(0x02); // param1
_signing_sha256.write(0x08); // param2(1) _signing_sha256.write(0x08); // param2(1)
@@ -276,26 +290,40 @@ static void signerCalculateSignature(MyMessage &msg, bool signing) {
_signing_sha256.write(0xEE); // SN[8] _signing_sha256.write(0xEE); // SN[8]
_signing_sha256.write(0x01); // SN[0] _signing_sha256.write(0x01); // SN[0]
_signing_sha256.write(0x23); // SN[1] _signing_sha256.write(0x23); // SN[1]
for (int i=0; i<25; i++) _signing_sha256.write(0x00); for (int i=0; i<25; i++) {
for (int i=0; i<32; i++) _signing_sha256.write(signing ? _signing_signing_nonce[i] : _signing_verifying_nonce[i]); _signing_sha256.write(0x00);
}
for (int i=0; i<32; i++) {
_signing_sha256.write(signing ? _signing_signing_nonce[i] : _signing_verifying_nonce[i]);
}
// Purge nonce when used // Purge nonce when used
memset(signing ? _signing_signing_nonce : _signing_verifying_nonce, 0xAA, 32); memset(signing ? _signing_signing_nonce : _signing_verifying_nonce, 0xAA, 32);
memcpy(_signing_temp_message, _signing_sha256.result(), 32); memcpy(_signing_temp_message, _signing_sha256.result(), 32);
// Feed "message" to HMAC calculator // Feed "message" to HMAC calculator
_signing_sha256.initHmac(_signing_hmac_key,32); // Set the key to use _signing_sha256.initHmac(_signing_hmac_key,32); // Set the key to use
for (int i=0; i<32; i++) _signing_sha256.write(0x00); // 32 bytes zeroes for (int i=0; i<32; i++) {
for (int i=0; i<32; i++) _signing_sha256.write(_signing_temp_message[i]); // 32 bytes digest _signing_sha256.write(0x00); // 32 bytes zeroes
}
for (int i=0; i<32; i++) {
_signing_sha256.write(_signing_temp_message[i]); // 32 bytes digest
}
_signing_sha256.write(0x11); // OPCODE _signing_sha256.write(0x11); // OPCODE
_signing_sha256.write(0x04); // Mode _signing_sha256.write(0x04); // Mode
_signing_sha256.write(0x00); // SlotID(1) _signing_sha256.write(0x00); // SlotID(1)
_signing_sha256.write(0x00); // SlotID(2) _signing_sha256.write(0x00); // SlotID(2)
for (int i=0; i<11; i++) _signing_sha256.write(0x00); // 11 bytes zeroes for (int i=0; i<11; i++) {
_signing_sha256.write(0x00); // 11 bytes zeroes
}
_signing_sha256.write(0xEE); // SN[8] _signing_sha256.write(0xEE); // SN[8]
for (int i=0; i<4; i++) _signing_sha256.write(0x00); // 4 bytes zeroes for (int i=0; i<4; i++) {
_signing_sha256.write(0x00); // 4 bytes zeroes
}
_signing_sha256.write(0x01); // SN[0] _signing_sha256.write(0x01); // SN[0]
_signing_sha256.write(0x23); // SN[1] _signing_sha256.write(0x23); // SN[1]
for (int i=0; i<2; i++) _signing_sha256.write(0x00); // 2 bytes zeroes for (int i=0; i<2; i++) {
_signing_sha256.write(0x00); // 2 bytes zeroes
}
memcpy(_signing_hmac, _signing_sha256.resultHmac(), 32); memcpy(_signing_hmac, _signing_sha256.resultHmac(), 32);
+31 -26
View File
@@ -112,7 +112,7 @@ void stInitUpdate(void) {
// ID invalid (0 or 255) // ID invalid (0 or 255)
transportSwitchSM(stFailure); transportSwitchSM(stFailure);
} }
#endif #endif
} }
} }
@@ -191,7 +191,7 @@ void stIDUpdate(void) {
TRANSPORT_DEBUG(PSTR("TSM:ID:OK\n")); TRANSPORT_DEBUG(PSTR("TSM:ID:OK\n"));
setIndication(INDICATION_GOT_NODEID); setIndication(INDICATION_GOT_NODEID);
// proceed to next state // proceed to next state
transportSwitchSM(stUplink); transportSwitchSM(stUplink);
} }
else if (transportTimeInState() > MY_TRANSPORT_STATE_TIMEOUT_MS) { else if (transportTimeInState() > MY_TRANSPORT_STATE_TIMEOUT_MS) {
// timeout // timeout
@@ -261,7 +261,7 @@ void stReadyTransition(void) {
// stReadyUpdate: monitors link // stReadyUpdate: monitors link
void stReadyUpdate(void) { void stReadyUpdate(void) {
#if defined(MY_GATEWAY_FEATURE) #if defined(MY_GATEWAY_FEATURE)
if (hwMillis() - _lastNetworkDiscovery > MY_TRANSPORT_DISCOVERY_INTERVAL_MS) { if (hwMillis() - _lastNetworkDiscovery > MY_TRANSPORT_DISCOVERY_INTERVAL_MS) {
_lastNetworkDiscovery = hwMillis(); _lastNetworkDiscovery = hwMillis();
TRANSPORT_DEBUG(PSTR("TSM:READY:NWD REQ\n")); // send transport network discovery TRANSPORT_DEBUG(PSTR("TSM:READY:NWD REQ\n")); // send transport network discovery
@@ -319,7 +319,9 @@ void transportSwitchSM(transportState& newState) {
else { else {
_transportSM.stateRetries++; // increment retries _transportSM.stateRetries++; // increment retries
} }
if (_transportSM.currentState->Transition) _transportSM.currentState->Transition(); // State transition if (_transportSM.currentState->Transition) {
_transportSM.currentState->Transition(); // State transition
}
_transportSM.stateEnter = hwMillis(); // save time _transportSM.stateEnter = hwMillis(); // save time
} }
@@ -328,7 +330,9 @@ uint32_t transportTimeInState(void) {
} }
void transportUpdateSM(void) { void transportUpdateSM(void) {
if (_transportSM.currentState->Update) _transportSM.currentState->Update(); if (_transportSM.currentState->Update) {
_transportSM.currentState->Update();
}
} }
bool isTransportReady(void) { bool isTransportReady(void) {
@@ -363,7 +367,7 @@ void transportInitialise(void) {
// update TSM and process incoming messages // update TSM and process incoming messages
void transportProcess(void) { void transportProcess(void) {
// update state machine // update state machine
transportUpdateSM(); transportUpdateSM();
// process transport FIFO // process transport FIFO
transportProcessFIFO(); transportProcessFIFO();
} }
@@ -415,7 +419,7 @@ bool transportAssignNodeID(const uint8_t newNodeId) {
bool transportRouteMessage(MyMessage &message) { bool transportRouteMessage(MyMessage &message) {
const uint8_t destination = message.destination; const uint8_t destination = message.destination;
uint8_t route = _nc.parentNodeId; // by default, all traffic is routed via parent node uint8_t route = _nc.parentNodeId; // by default, all traffic is routed via parent node
if (_transportSM.findingParentNode && destination != BROADCAST_ADDRESS) { if (_transportSM.findingParentNode && destination != BROADCAST_ADDRESS) {
TRANSPORT_DEBUG(PSTR("!TSF:RTE:FPAR ACTIVE\n")); // find parent active, message not sent TRANSPORT_DEBUG(PSTR("!TSF:RTE:FPAR ACTIVE\n")); // find parent active, message not sent
// request to send a non-BC message while finding parent active, abort // request to send a non-BC message while finding parent active, abort
@@ -438,7 +442,7 @@ bool transportRouteMessage(MyMessage &message) {
if (message.last != _nc.parentNodeId) { if (message.last != _nc.parentNodeId) {
// message not from parent, i.e. child node - route it to parent // message not from parent, i.e. child node - route it to parent
route = _nc.parentNodeId; route = _nc.parentNodeId;
} }
else { else {
// route unknown and msg received from parent, send it to destination assuming in rx radius // route unknown and msg received from parent, send it to destination assuming in rx radius
route = destination; route = destination;
@@ -464,7 +468,9 @@ bool transportRouteMessage(MyMessage &message) {
else _transportSM.failedUplinkTransmissions = 0u; else _transportSM.failedUplinkTransmissions = 0u;
} }
#else #else
if(!result) setIndication(INDICATION_ERR_TX); if(!result) {
setIndication(INDICATION_ERR_TX);
}
#endif #endif
return result; return result;
@@ -532,7 +538,7 @@ void transportProcessMessage(void) {
setIndication(INDICATION_RX); setIndication(INDICATION_RX);
const uint8_t payloadLength = transportReceive((uint8_t *)&_msg); const uint8_t payloadLength = transportReceive((uint8_t *)&_msg);
// get message length and limit size // get message length and limit size
const uint8_t msgLength = min(mGetLength(_msg), (uint8_t)MAX_PAYLOAD); const uint8_t msgLength = min(mGetLength(_msg), (uint8_t)MAX_PAYLOAD);
// calculate expected length // calculate expected length
const uint8_t expectedMessageLength = HEADER_SIZE + (mGetSigned(_msg) ? MAX_PAYLOAD : msgLength); const uint8_t expectedMessageLength = HEADER_SIZE + (mGetSigned(_msg) ? MAX_PAYLOAD : msgLength);
const uint8_t command = mGetCommand(_msg); const uint8_t command = mGetCommand(_msg);
@@ -557,12 +563,12 @@ void transportProcessMessage(void) {
TRANSPORT_DEBUG(PSTR("!TSF:MSG:PVER,%d=%d\n"), mGetVersion(_msg), PROTOCOL_VERSION); // protocol version mismatch TRANSPORT_DEBUG(PSTR("!TSF:MSG:PVER,%d=%d\n"), mGetVersion(_msg), PROTOCOL_VERSION); // protocol version mismatch
return; return;
} }
// Reject messages that do not pass verification // Reject messages that do not pass verification
if (!signerVerifyMsg(_msg)) { if (!signerVerifyMsg(_msg)) {
setIndication(INDICATION_ERR_SIGN); setIndication(INDICATION_ERR_SIGN);
TRANSPORT_DEBUG(PSTR("!TSF:MSG:SIGN VERIFY FAIL\n")); TRANSPORT_DEBUG(PSTR("!TSF:MSG:SIGN VERIFY FAIL\n"));
return; return;
} }
// update routing table if msg not from parent // update routing table if msg not from parent
@@ -580,7 +586,7 @@ void transportProcessMessage(void) {
// set message received flag // set message received flag
_transportSM.msgReceived = true; _transportSM.msgReceived = true;
// Is message addressed to this node? // Is message addressed to this node?
if (destination == _nc.nodeId) { if (destination == _nc.nodeId) {
// prevent buffer overflow by limiting max. possible message length (5 bits=31 bytes max) to MAX_PAYLOAD (25 bytes) // prevent buffer overflow by limiting max. possible message length (5 bits=31 bytes max) to MAX_PAYLOAD (25 bytes)
@@ -590,14 +596,14 @@ void transportProcessMessage(void) {
// Check if sender requests an ack back. // Check if sender requests an ack back.
if (mGetRequestAck(_msg)) { if (mGetRequestAck(_msg)) {
TRANSPORT_DEBUG(PSTR("TSF:MSG:ACK REQ\n")); // ACK requested TRANSPORT_DEBUG(PSTR("TSF:MSG:ACK REQ\n")); // ACK requested
_msgTmp = _msg; // Copy message _msgTmp = _msg; // Copy message
mSetRequestAck(_msgTmp, false); // Reply without ack flag (otherwise we would end up in an eternal loop) mSetRequestAck(_msgTmp, false); // Reply without ack flag (otherwise we would end up in an eternal loop)
mSetAck(_msgTmp, true); // set ACK flag mSetAck(_msgTmp, true); // set ACK flag
_msgTmp.sender = _nc.nodeId; _msgTmp.sender = _nc.nodeId;
_msgTmp.destination = sender; _msgTmp.destination = sender;
// send ACK, use transportSendRoute since ACK reply is not internal, i.e. if !transportOK do not reply // send ACK, use transportSendRoute since ACK reply is not internal, i.e. if !transportOK do not reply
(void)transportSendRoute(_msgTmp); (void)transportSendRoute(_msgTmp);
} }
if(!mGetAck(_msg)) { if(!mGetAck(_msg)) {
// only process if not ACK // only process if not ACK
if (command == C_INTERNAL) { if (command == C_INTERNAL) {
@@ -683,7 +689,7 @@ void transportProcessMessage(void) {
if (receive) { if (receive) {
receive(_msg); receive(_msg);
} }
} }
else if (destination == BROADCAST_ADDRESS) { else if (destination == BROADCAST_ADDRESS) {
TRANSPORT_DEBUG(PSTR("TSF:MSG:BC\n")); // broadcast msg TRANSPORT_DEBUG(PSTR("TSF:MSG:BC\n")); // broadcast msg
if (command == C_INTERNAL) { if (command == C_INTERNAL) {
@@ -707,7 +713,7 @@ void transportProcessMessage(void) {
} }
} }
#endif #endif
return; // no further processing required, do not forward return; // no further processing required, do not forward
} }
} // isTransportReady } // isTransportReady
if (type == I_FIND_PARENT_RESPONSE) { if (type == I_FIND_PARENT_RESPONSE) {
@@ -732,12 +738,14 @@ void transportProcessMessage(void) {
(void)transportRouteMessage(_msg); (void)transportRouteMessage(_msg);
} }
#endif #endif
// Callback for BC, only for non-internal messages // Callback for BC, only for non-internal messages
if (command != C_INTERNAL) { if (command != C_INTERNAL) {
#if !defined(MY_GATEWAY_FEATURE) #if !defined(MY_GATEWAY_FEATURE)
// only proceed if message received from parent // only proceed if message received from parent
if (last != _nc.parentNodeId) return; if (last != _nc.parentNodeId) {
return;
}
#endif #endif
#if defined(MY_GATEWAY_FEATURE) #if defined(MY_GATEWAY_FEATURE)
// Hand over message to controller // Hand over message to controller
@@ -747,10 +755,10 @@ void transportProcessMessage(void) {
receive(_msg); receive(_msg);
} }
} }
} }
else { else {
// msg not to us and not BC, relay msg // msg not to us and not BC, relay msg
#if defined(MY_REPEATER_FEATURE) #if defined(MY_REPEATER_FEATURE)
if (isTransportReady()) { if (isTransportReady()) {
TRANSPORT_DEBUG(PSTR("TSF:MSG:REL MSG\n")); // relay msg TRANSPORT_DEBUG(PSTR("TSF:MSG:REL MSG\n")); // relay msg
@@ -817,7 +825,7 @@ bool transportSendWrite(const uint8_t to, MyMessage &message) {
setIndication(INDICATION_ERR_SIGN); setIndication(INDICATION_ERR_SIGN);
return false; return false;
} }
// msg length changes if signed // msg length changes if signed
const uint8_t totalMsgLength = HEADER_SIZE + ( mGetSigned(message) ? MAX_PAYLOAD : mGetLength(message) ); const uint8_t totalMsgLength = HEADER_SIZE + ( mGetSigned(message) ? MAX_PAYLOAD : mGetLength(message) );
@@ -873,6 +881,3 @@ uint8_t transportGetRoute(const uint8_t node) {
#endif #endif
return result; return result;
} }
// EOF MyTransport.cpp
+6 -4
View File
@@ -125,7 +125,9 @@ bool _serialProcess()
{ {
char inch; char inch;
unsigned char i; unsigned char i;
if (!_dev.available()) return false; if (!_dev.available()) {
return false;
}
while(_dev.available()) { while(_dev.available()) {
inch = _dev.read(); inch = _dev.read();
@@ -263,7 +265,9 @@ bool transportSend(uint8_t to, const void* data, uint8_t len)
#endif #endif
// Start of header by writing multiple SOH // Start of header by writing multiple SOH
for(byte w=0;w<1;w++) _dev.write(SOH); for(byte w=0;w<1;w++) {
_dev.write(SOH);
}
_dev.write(to); // Destination address _dev.write(to); // Destination address
cs += to; cs += to;
_dev.write(_nodeId); // Source address _dev.write(_nodeId); // Source address
@@ -351,5 +355,3 @@ uint8_t transportReceive(void* data) {
void transportPowerDown() { void transportPowerDown() {
// Nothing to shut down here // Nothing to shut down here
} }
+18
View File
@@ -1,3 +1,21 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
/*** /***
* This file defines the Sensor library version number * This file defines the Sensor library version number
* Normally, contributors should not modify this directly * Normally, contributors should not modify this directly
+30 -22
View File
@@ -36,13 +36,13 @@
/* This version derived by Mark Tillotson 2012-01-23, tidied up, slimmed down /* This version derived by Mark Tillotson 2012-01-23, tidied up, slimmed down
and tailored to 8-bit microcontroller abilities and Arduino datatypes. and tailored to 8-bit microcontroller abilities and Arduino datatypes.
The s-box and inverse s-box were retained as tables (0.5kB PROGMEM) but all The s-box and inverse s-box were retained as tables (0.5kB PROGMEM) but all
the other transformations are coded to save table space. Many efficiency the other transformations are coded to save table space. Many efficiency
improvments to the routines mix_sub_columns() and inv_mix_sub_columns() improvments to the routines mix_sub_columns() and inv_mix_sub_columns()
(mainly common sub-expression elimination). (mainly common sub-expression elimination).
Only the routines with precalculated subkey schedule are retained (together Only the routines with precalculated subkey schedule are retained (together
with set_key() - this does however mean each AES object takes 240 bytes of with set_key() - this does however mean each AES object takes 240 bytes of
RAM, alas) RAM, alas)
The CBC routines side-effect the iv argument (so that successive calls work The CBC routines side-effect the iv argument (so that successive calls work
@@ -218,7 +218,7 @@ static void inv_mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
byte a8 = f2(a4), b8 = f2(b4), c8 = f2(c4), d8 = f2(d4) ; byte a8 = f2(a4), b8 = f2(b4), c8 = f2(c4), d8 = f2(d4) ;
byte a9 = a8 ^ a1,b9 = b8 ^ b1,c9 = c8 ^ c1,d9 = d8 ^ d1 ; byte a9 = a8 ^ a1,b9 = b8 ^ b1,c9 = c8 ^ c1,d9 = d8 ^ d1 ;
byte ac = a8 ^ a4,bc = b8 ^ b4,cc = c8 ^ c4,dc = d8 ^ d4 ; byte ac = a8 ^ a4,bc = b8 ^ b4,cc = c8 ^ c4,dc = d8 ^ d4 ;
dt[i] = is_box (ac^a2 ^ b9^b2 ^ cc^c1 ^ d9) ; dt[i] = is_box (ac^a2 ^ b9^b2 ^ cc^c1 ^ d9) ;
dt[(i+5)&15] = is_box (a9 ^ bc^b2 ^ c9^c2 ^ dc^d1) ; dt[(i+5)&15] = is_box (a9 ^ bc^b2 ^ c9^c2 ^ dc^d1) ;
dt[(i+10)&15] = is_box (ac^a1 ^ b9 ^ cc^c2 ^ d9^d2) ; dt[(i+10)&15] = is_box (ac^a1 ^ b9 ^ cc^c2 ^ d9^d2) ;
@@ -257,32 +257,33 @@ byte AES::set_key (byte key [], int keylen)
switch (keylen) switch (keylen)
{ {
case 16: case 16:
case 128: case 128:
keylen = 16; // 10 rounds keylen = 16; // 10 rounds
round = 10 ; round = 10 ;
break; break;
case 24: case 24:
case 192: case 192:
keylen = 24; // 12 rounds keylen = 24; // 12 rounds
round = 12 ; round = 12 ;
break; break;
case 32: case 32:
case 256: case 256:
keylen = 32; // 14 rounds keylen = 32; // 14 rounds
round = 14 ; round = 14 ;
break; break;
default: default:
round = 0; round = 0;
return AES_FAILURE; return AES_FAILURE;
} }
hi = (round + 1) << 4 ; hi = (round + 1) << 4 ;
copy_n_bytes (key_sched, key, keylen) ; copy_n_bytes (key_sched, key, keylen) ;
byte t[4] ; byte t[4] ;
byte next = keylen ; byte next = keylen ;
for (byte cc = keylen, rc = 1 ; cc < hi ; cc += N_COL) for (byte cc = keylen, rc = 1 ; cc < hi ; cc += N_COL)
{ {
for (byte i = 0 ; i < N_COL ; i++) for (byte i = 0 ; i < N_COL ; i++) {
t[i] = key_sched [cc-4+i] ; t[i] = key_sched [cc-4+i] ;
}
if (cc == next) if (cc == next)
{ {
next += keylen ; next += keylen ;
@@ -295,12 +296,14 @@ byte AES::set_key (byte key [], int keylen)
} }
else if (keylen == 32 && (cc & 31) == 16) else if (keylen == 32 && (cc & 31) == 16)
{ {
for (byte i = 0 ; i < 4 ; i++) for (byte i = 0 ; i < 4 ; i++) {
t[i] = s_box (t[i]) ; t[i] = s_box (t[i]) ;
}
} }
byte tt = cc - keylen ; byte tt = cc - keylen ;
for (byte i = 0 ; i < N_COL ; i++) for (byte i = 0 ; i < N_COL ; i++) {
key_sched [cc + i] = key_sched [tt + i] ^ t[i] ; key_sched [cc + i] = key_sched [tt + i] ^ t[i] ;
}
} }
return AES_SUCCESS ; return AES_SUCCESS ;
} }
@@ -309,8 +312,9 @@ byte AES::set_key (byte key [], int keylen)
void AES::clean () void AES::clean ()
{ {
for (byte i = 0 ; i < KEY_SCHEDULE_BYTES ; i++) for (byte i = 0 ; i < KEY_SCHEDULE_BYTES ; i++) {
key_sched [i] = 0 ; key_sched [i] = 0 ;
}
round = 0 ; round = 0 ;
} }
@@ -340,7 +344,7 @@ byte AES::encrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK])
copy_and_key (s1, plain, (byte*) (key_sched)) ; copy_and_key (s1, plain, (byte*) (key_sched)) ;
for (r = 1 ; r < round ; r++) for (r = 1 ; r < round ; r++)
{ {
byte s2 [N_BLOCK] ; byte s2 [N_BLOCK] ;
mix_sub_columns (s2, s1) ; mix_sub_columns (s2, s1) ;
copy_and_key (s1, s2, (byte*) (key_sched + r * N_BLOCK)) ; copy_and_key (s1, s2, (byte*) (key_sched + r * N_BLOCK)) ;
@@ -360,8 +364,9 @@ byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block, byte iv [N_BLOC
while (n_block--) while (n_block--)
{ {
xor_block (iv, plain) ; xor_block (iv, plain) ;
if (encrypt (iv, iv) != AES_SUCCESS) if (encrypt (iv, iv) != AES_SUCCESS) {
return AES_FAILURE ; return AES_FAILURE ;
}
copy_n_bytes (cipher, iv, N_BLOCK) ; copy_n_bytes (cipher, iv, N_BLOCK) ;
plain += N_BLOCK ; plain += N_BLOCK ;
cipher += N_BLOCK ; cipher += N_BLOCK ;
@@ -376,8 +381,9 @@ byte AES::cbc_encrypt (byte * plain, byte * cipher, int n_block)
while (n_block--) while (n_block--)
{ {
xor_block (iv, plain) ; xor_block (iv, plain) ;
if (encrypt (iv, iv) != AES_SUCCESS) if (encrypt (iv, iv) != AES_SUCCESS) {
return AES_FAILURE ; return AES_FAILURE ;
}
copy_n_bytes (cipher, iv, N_BLOCK) ; copy_n_bytes (cipher, iv, N_BLOCK) ;
plain += N_BLOCK ; plain += N_BLOCK ;
cipher += N_BLOCK ; cipher += N_BLOCK ;
@@ -411,13 +417,14 @@ byte AES::decrypt (byte plain [N_BLOCK], byte cipher [N_BLOCK])
/******************************************************************************/ /******************************************************************************/
byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK]) byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOCK])
{ {
while (n_block--) while (n_block--)
{ {
byte tmp [N_BLOCK] ; byte tmp [N_BLOCK] ;
copy_n_bytes (tmp, cipher, N_BLOCK) ; copy_n_bytes (tmp, cipher, N_BLOCK) ;
if (decrypt (cipher, plain) != AES_SUCCESS) if (decrypt (cipher, plain) != AES_SUCCESS) {
return AES_FAILURE ; return AES_FAILURE ;
}
xor_block (plain, iv) ; xor_block (plain, iv) ;
copy_n_bytes (iv, tmp, N_BLOCK) ; copy_n_bytes (iv, tmp, N_BLOCK) ;
plain += N_BLOCK ; plain += N_BLOCK ;
@@ -429,13 +436,14 @@ byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block, byte iv [N_BLOC
/******************************************************************************/ /******************************************************************************/
byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block) byte AES::cbc_decrypt (byte * cipher, byte * plain, int n_block)
{ {
while (n_block--) while (n_block--)
{ {
byte tmp [N_BLOCK] ; byte tmp [N_BLOCK] ;
copy_n_bytes (tmp, cipher, N_BLOCK) ; copy_n_bytes (tmp, cipher, N_BLOCK) ;
if (decrypt (cipher, plain) != AES_SUCCESS) if (decrypt (cipher, plain) != AES_SUCCESS) {
return AES_FAILURE ; return AES_FAILURE ;
}
xor_block (plain, iv) ; xor_block (plain, iv) ;
copy_n_bytes (iv, tmp, N_BLOCK) ; copy_n_bytes (iv, tmp, N_BLOCK) ;
plain += N_BLOCK ; plain += N_BLOCK ;
@@ -505,7 +513,7 @@ void AES::padPlaintext(void* in,byte* out)
/******************************************************************************/ /******************************************************************************/
bool AES::CheckPad(byte* in,int lsize){ bool AES::CheckPad(byte* in,int lsize){
if (in[lsize-1] <= 0x0f){ if (in[lsize-1] <= 0x0f){
int lpad = (int)in[lsize-1]; int lpad = (int)in[lsize-1];
for (int i = lsize - 1; i >= lsize-lpad; i--){ for (int i = lsize - 1; i >= lsize-lpad; i--){
if (arr_pad[lpad - 1] != in[i]){ if (arr_pad[lpad - 1] != in[i]){
+75 -40
View File
@@ -24,10 +24,12 @@ static void swi_set_signal_pin(uint8_t is_high)
{ {
SHA204_SET_OUTPUT(); SHA204_SET_OUTPUT();
if (is_high) if (is_high) {
SHA204_POUT_HIGH(); SHA204_POUT_HIGH();
else }
SHA204_POUT_LOW(); else {
SHA204_POUT_LOW();
}
} }
static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer) static uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer)
@@ -109,8 +111,9 @@ static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
while (--timeout_count > 0) while (--timeout_count > 0)
{ {
// Wait for falling edge. // Wait for falling edge.
if (SHA204_PIN_READ() == 0) if (SHA204_PIN_READ() == 0) {
break; break;
}
} }
if (timeout_count == 0) if (timeout_count == 0)
@@ -159,8 +162,9 @@ static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
{ {
do do
{ {
if (SHA204_PIN_READ() != 0) if (SHA204_PIN_READ() != 0) {
break; break;
}
} while (timeout_count-- > 0); } while (timeout_count-- > 0);
} }
@@ -169,16 +173,18 @@ static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
buffer[i] |= bit_mask; // received "one" bit buffer[i] |= bit_mask; // received "one" bit
} }
if (status != SWI_FUNCTION_RETCODE_SUCCESS) if (status != SWI_FUNCTION_RETCODE_SUCCESS) {
break; break;
}
} }
interrupts(); //swi_enable_interrupts(); interrupts(); //swi_enable_interrupts();
if (status == SWI_FUNCTION_RETCODE_TIMEOUT) if (status == SWI_FUNCTION_RETCODE_TIMEOUT)
{ {
if (i > 0) if (i > 0) {
// Indicate that we timed out after having received at least one byte. // Indicate that we timed out after having received at least one byte.
status = SWI_FUNCTION_RETCODE_RX_FAIL; status = SWI_FUNCTION_RETCODE_RX_FAIL;
}
} }
return status; return status;
} }
@@ -191,8 +197,9 @@ static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
uint8_t i; uint8_t i;
uint8_t ret_code; uint8_t ret_code;
for (i = 0; i < size; i++) for (i = 0; i < size; i++) {
response[i] = 0; response[i] = 0;
}
(void) swi_send_byte(SHA204_SWI_FLAG_TX); (void) swi_send_byte(SHA204_SWI_FLAG_TX);
@@ -200,8 +207,9 @@ static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
if (ret_code == SWI_FUNCTION_RETCODE_SUCCESS || ret_code == SWI_FUNCTION_RETCODE_RX_FAIL) if (ret_code == SWI_FUNCTION_RETCODE_SUCCESS || ret_code == SWI_FUNCTION_RETCODE_RX_FAIL)
{ {
count_byte = response[SHA204_BUFFER_POS_COUNT]; count_byte = response[SHA204_BUFFER_POS_COUNT];
if ((count_byte < SHA204_RSP_SIZE_MIN) || (count_byte > size)) if ((count_byte < SHA204_RSP_SIZE_MIN) || (count_byte > size)) {
return SHA204_INVALID_SIZE; return SHA204_INVALID_SIZE;
}
return SHA204_SUCCESS; return SHA204_SUCCESS;
} }
@@ -209,10 +217,12 @@ static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
// Translate error so that the Communication layer // Translate error so that the Communication layer
// can distinguish between a real error or the // can distinguish between a real error or the
// device being busy executing a command. // device being busy executing a command.
if (ret_code == SWI_FUNCTION_RETCODE_TIMEOUT) if (ret_code == SWI_FUNCTION_RETCODE_TIMEOUT) {
return SHA204_RX_NO_RESPONSE; return SHA204_RX_NO_RESPONSE;
else }
else {
return SHA204_RX_FAIL; return SHA204_RX_FAIL;
}
} }
/* Communication functions */ /* Communication functions */
@@ -223,8 +233,9 @@ static uint8_t sha204c_resync(uint8_t size, uint8_t *response)
// (step 1 of the re-synchronization process). // (step 1 of the re-synchronization process).
delay(SHA204_SYNC_TIMEOUT); delay(SHA204_SYNC_TIMEOUT);
uint8_t ret_code = sha204p_receive_response(size, response); uint8_t ret_code = sha204p_receive_response(size, response);
if (ret_code == SHA204_SUCCESS) if (ret_code == SHA204_SUCCESS) {
return ret_code; return ret_code;
}
// We lost communication. Send a Wake pulse and try // We lost communication. Send a Wake pulse and try
// to receive a response (steps 2 and 3 of the // to receive a response (steps 2 and 3 of the
@@ -261,17 +272,21 @@ static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uin
{ {
// Send command. // Send command.
ret_code = swi_send_byte(SHA204_SWI_FLAG_CMD); ret_code = swi_send_byte(SHA204_SWI_FLAG_CMD);
if (ret_code != SWI_FUNCTION_RETCODE_SUCCESS) if (ret_code != SWI_FUNCTION_RETCODE_SUCCESS) {
ret_code = SHA204_COMM_FAIL; ret_code = SHA204_COMM_FAIL;
else }
else {
ret_code = swi_send_bytes(count, tx_buffer); ret_code = swi_send_bytes(count, tx_buffer);
}
if (ret_code != SHA204_SUCCESS) if (ret_code != SHA204_SUCCESS)
{ {
if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) {
return ret_code; // The device seems to be dead in the water. return ret_code; // The device seems to be dead in the water.
else }
else {
continue; continue;
}
} }
// Wait minimum command execution time and then start polling for a response. // Wait minimum command execution time and then start polling for a response.
@@ -282,8 +297,9 @@ static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uin
while (n_retries_receive-- > 0) while (n_retries_receive-- > 0)
{ {
// Reset response buffer. // Reset response buffer.
for (i = 0; i < rx_size; i++) for (i = 0; i < rx_size; i++) {
rx_buffer[i] = 0; rx_buffer[i] = 0;
}
// Poll for response. // Poll for response.
timeout_countdown = execution_timeout_us; timeout_countdown = execution_timeout_us;
@@ -297,11 +313,13 @@ static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uin
if (ret_code == SHA204_RX_NO_RESPONSE) if (ret_code == SHA204_RX_NO_RESPONSE)
{ {
// We did not receive a response. Re-synchronize and send command again. // We did not receive a response. Re-synchronize and send command again.
if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) {
// The device seems to be dead in the water. // The device seems to be dead in the water.
return ret_code; return ret_code;
else }
else {
break; break;
}
} }
// Check whether we received a valid response. // Check whether we received a valid response.
@@ -309,16 +327,19 @@ static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uin
{ {
// We see 0xFF for the count when communication got out of sync. // We see 0xFF for the count when communication got out of sync.
ret_code_resync = sha204c_resync(rx_size, rx_buffer); ret_code_resync = sha204c_resync(rx_size, rx_buffer);
if (ret_code_resync == SHA204_SUCCESS) if (ret_code_resync == SHA204_SUCCESS) {
// We did not have to wake up the device. Try receiving response again. // We did not have to wake up the device. Try receiving response again.
continue; continue;
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) }
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) {
// We could re-synchronize, but only after waking up the device. // We could re-synchronize, but only after waking up the device.
// Re-send command. // Re-send command.
break; break;
else }
else {
// We failed to re-synchronize. // We failed to re-synchronize.
return ret_code; return ret_code;
}
} }
// We received a response of valid size. // We received a response of valid size.
@@ -327,19 +348,22 @@ static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uin
if (ret_code == SHA204_SUCCESS) if (ret_code == SHA204_SUCCESS)
{ {
// Received valid response. // Received valid response.
if (rx_buffer[SHA204_BUFFER_POS_COUNT] > SHA204_RSP_SIZE_MIN) if (rx_buffer[SHA204_BUFFER_POS_COUNT] > SHA204_RSP_SIZE_MIN) {
// Received non-status response. We are done. // Received non-status response. We are done.
return ret_code; return ret_code;
}
// Received status response. // Received status response.
status_byte = rx_buffer[SHA204_BUFFER_POS_STATUS]; status_byte = rx_buffer[SHA204_BUFFER_POS_STATUS];
// Translate the three possible device status error codes // Translate the three possible device status error codes
// into library return codes. // into library return codes.
if (status_byte == SHA204_STATUS_BYTE_PARSE) if (status_byte == SHA204_STATUS_BYTE_PARSE) {
return SHA204_PARSE_ERROR; return SHA204_PARSE_ERROR;
if (status_byte == SHA204_STATUS_BYTE_EXEC) }
if (status_byte == SHA204_STATUS_BYTE_EXEC) {
return SHA204_CMD_FAIL; return SHA204_CMD_FAIL;
}
if (status_byte == SHA204_STATUS_BYTE_COMM) if (status_byte == SHA204_STATUS_BYTE_COMM)
{ {
// In case of the device status byte indicating a communication // In case of the device status byte indicating a communication
@@ -359,16 +383,19 @@ static uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uin
{ {
// Received response with incorrect CRC. // Received response with incorrect CRC.
ret_code_resync = sha204c_resync(rx_size, rx_buffer); ret_code_resync = sha204c_resync(rx_size, rx_buffer);
if (ret_code_resync == SHA204_SUCCESS) if (ret_code_resync == SHA204_SUCCESS) {
// We did not have to wake up the device. Try receiving response again. // We did not have to wake up the device. Try receiving response again.
continue; continue;
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) }
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) {
// We could re-synchronize, but only after waking up the device. // We could re-synchronize, but only after waking up the device.
// Re-send command. // Re-send command.
break; break;
else }
else {
// We failed to re-synchronize. // We failed to re-synchronize.
return ret_code; return ret_code;
}
} // block end of check response consistency } // block end of check response consistency
} // block end of receive retry loop } // block end of receive retry loop
@@ -418,8 +445,9 @@ static void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc)
// Shift CRC to the left by 1. // Shift CRC to the left by 1.
crc_register <<= 1; crc_register <<= 1;
if ((data_bit ^ crc_bit) != 0) if ((data_bit ^ crc_bit) != 0) {
crc_register ^= polynom; crc_register ^= polynom;
}
} }
} }
crc[0] = (uint8_t) (crc_register & 0x00FF); crc[0] = (uint8_t) (crc_register & 0x00FF);
@@ -475,22 +503,27 @@ uint8_t atsha204_wakeup(uint8_t *response)
delay(SHA204_WAKEUP_DELAY); delay(SHA204_WAKEUP_DELAY);
uint8_t ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response); uint8_t ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response);
if (ret_code != SHA204_SUCCESS) if (ret_code != SHA204_SUCCESS) {
return ret_code; return ret_code;
}
// Verify status response. // Verify status response.
if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN) if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN) {
ret_code = SHA204_INVALID_SIZE; ret_code = SHA204_INVALID_SIZE;
else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP) }
else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP) {
ret_code = SHA204_COMM_FAIL; ret_code = SHA204_COMM_FAIL;
}
else else
{ {
if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33) if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33)
|| (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43)) || (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43)) {
ret_code = SHA204_BAD_CRC; ret_code = SHA204_BAD_CRC;
}
} }
if (ret_code != SHA204_SUCCESS) if (ret_code != SHA204_SUCCESS) {
delay(SHA204_COMMAND_EXEC_MAX); delay(SHA204_COMMAND_EXEC_MAX);
}
return ret_code; return ret_code;
} }
@@ -580,14 +613,16 @@ uint8_t atsha204_getSerialNumber(uint8_t * response)
uint8_t returnCode = sha204m_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN03); uint8_t returnCode = sha204m_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN03);
if (!returnCode) if (!returnCode)
{ {
for (int i=0; i<4; i++) // store bytes 0-3 into respones array for (int i=0; i<4; i++) {// store bytes 0-3 into respones array
response[i] = readResponse[SHA204_BUFFER_POS_DATA+i]; response[i] = readResponse[SHA204_BUFFER_POS_DATA+i];
}
/* read from bytes 8->11 of config zone */ /* read from bytes 8->11 of config zone */
returnCode = sha204m_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN47); returnCode = sha204m_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN47);
for (int i=4; i<8; i++) // store bytes 4-7 of SN into response array for (int i=4; i<8; i++) {// store bytes 4-7 of SN into response array
response[i] = readResponse[SHA204_BUFFER_POS_DATA+(i-4)]; response[i] = readResponse[SHA204_BUFFER_POS_DATA+(i-4)];
}
if (!returnCode) if (!returnCode)
{ /* Finally if last two reads were successful, read byte 8 of the SN */ { /* Finally if last two reads were successful, read byte 8 of the SN */
+15 -7
View File
@@ -54,7 +54,7 @@ void Sha256Class::hashBlock() {
f=state.w[5]; f=state.w[5];
g=state.w[6]; g=state.w[6];
h=state.w[7]; h=state.w[7];
for (i=0; i<64; i++) { for (i=0; i<64; i++) {
if (i>=16) { if (i>=16) {
t1 = buffer.w[i&15] + buffer.w[(i-7)&15]; t1 = buffer.w[i&15] + buffer.w[(i-7)&15];
@@ -102,7 +102,9 @@ void Sha256Class::pad() {
// Pad with 0x80 followed by 0x00 until the end of the block // Pad with 0x80 followed by 0x00 until the end of the block
addUncounted(0x80); addUncounted(0x80);
while (bufferOffset != 56) addUncounted(0x00); while (bufferOffset != 56) {
addUncounted(0x00);
}
// Append length in the last 8 bytes // Append length in the last 8 bytes
addUncounted(0); // We're only using 32 bit lengths addUncounted(0); // We're only using 32 bit lengths
@@ -119,7 +121,7 @@ void Sha256Class::pad() {
uint8_t* Sha256Class::result(void) { uint8_t* Sha256Class::result(void) {
// Pad to complete the last block // Pad to complete the last block
pad(); pad();
// Swap byte order back // Swap byte order back
for (int i=0; i<8; i++) { for (int i=0; i<8; i++) {
uint32_t a,b; uint32_t a,b;
@@ -130,7 +132,7 @@ uint8_t* Sha256Class::result(void) {
b|=a>>24; b|=a>>24;
state.w[i]=b; state.w[i]=b;
} }
// Return pointer to hash (20 characters) // Return pointer to hash (20 characters)
return state.b; return state.b;
} }
@@ -147,7 +149,9 @@ void Sha256Class::initHmac(const uint8_t* key, int keyLength) {
if (keyLength > BLOCK_LENGTH) { if (keyLength > BLOCK_LENGTH) {
// Hash long keys // Hash long keys
init(); init();
for (;keyLength--;) write(*key++); for (;keyLength--;) {
write(*key++);
}
memcpy(keyBuffer,result(),HASH_LENGTH); memcpy(keyBuffer,result(),HASH_LENGTH);
} else { } else {
// Block length keys are used as is // Block length keys are used as is
@@ -166,7 +170,11 @@ uint8_t* Sha256Class::resultHmac(void) {
memcpy(innerHash,result(),HASH_LENGTH); memcpy(innerHash,result(),HASH_LENGTH);
// Calculate outer hash // Calculate outer hash
init(); init();
for (i=0; i<BLOCK_LENGTH; i++) write(keyBuffer[i] ^ HMAC_OPAD); for (i=0; i<BLOCK_LENGTH; i++) {
for (i=0; i<HASH_LENGTH; i++) write(innerHash[i]); write(keyBuffer[i] ^ HMAC_OPAD);
}
for (i=0; i<HASH_LENGTH; i++) {
write(innerHash[i]);
}
return result(); return result();
} }
+41 -18
View File
@@ -1,17 +1,17 @@
/* An Alternative Software Serial Library /* An Alternative Software Serial Library
* http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html * http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
* Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com * Copyright (c) 2014 PJRC.COM, LLC, Paul Stoffregen, paul@pjrc.com
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -108,8 +108,10 @@ void AltSoftSerial::writeByte(uint8_t b)
uint8_t intr_state, head; uint8_t intr_state, head;
head = tx_buffer_head + 1; head = tx_buffer_head + 1;
if (head >= TX_BUFFER_SIZE) head = 0; if (head >= TX_BUFFER_SIZE) {
while (tx_buffer_tail == head) ; // wait until space in buffer head = 0;
}
while (tx_buffer_tail == head) {} // wait until space in buffer
intr_state = SREG; intr_state = SREG;
cli(); cli();
if (tx_state) { if (tx_state) {
@@ -168,7 +170,9 @@ ISR(COMPARE_A_INTERRUPT)
DISABLE_INT_COMPARE_A(); DISABLE_INT_COMPARE_A();
} else { } else {
tx_state = 1; tx_state = 1;
if (++tail >= TX_BUFFER_SIZE) tail = 0; if (++tail >= TX_BUFFER_SIZE) {
tail = 0;
}
tx_buffer_tail = tail; tx_buffer_tail = tail;
tx_byte = tx_buffer[tail]; tx_byte = tx_buffer[tail];
tx_bit = 0; tx_bit = 0;
@@ -180,7 +184,7 @@ ISR(COMPARE_A_INTERRUPT)
void AltSoftSerial::flushOutput(void) void AltSoftSerial::flushOutput(void)
{ {
while (tx_state) /* wait */ ; while (tx_state) {}/* wait */
} }
@@ -216,14 +220,18 @@ ISR(CAPTURE_INTERRUPT)
target = rx_target; target = rx_target;
while (1) { while (1) {
offset = capture - target; offset = capture - target;
if (offset < 0) break; if (offset < 0) {
break;
}
rx_byte = (rx_byte >> 1) | rx_bit; rx_byte = (rx_byte >> 1) | rx_bit;
target += ticks_per_bit; target += ticks_per_bit;
state++; state++;
if (state >= 9) { if (state >= 9) {
DISABLE_INT_COMPARE_B(); DISABLE_INT_COMPARE_B();
head = rx_buffer_head + 1; head = rx_buffer_head + 1;
if (head >= RX_BUFFER_SIZE) head = 0; if (head >= RX_BUFFER_SIZE) {
head = 0;
}
if (head != rx_buffer_tail) { if (head != rx_buffer_tail) {
rx_buffer[head] = rx_byte; rx_buffer[head] = rx_byte;
rx_buffer_head = head; rx_buffer_head = head;
@@ -253,7 +261,9 @@ ISR(COMPARE_B_INTERRUPT)
state++; state++;
} }
head = rx_buffer_head + 1; head = rx_buffer_head + 1;
if (head >= RX_BUFFER_SIZE) head = 0; if (head >= RX_BUFFER_SIZE) {
head = 0;
}
if (head != rx_buffer_tail) { if (head != rx_buffer_tail) {
rx_buffer[head] = rx_byte; rx_buffer[head] = rx_byte;
rx_buffer_head = head; rx_buffer_head = head;
@@ -271,8 +281,12 @@ int AltSoftSerial::read(void)
head = rx_buffer_head; head = rx_buffer_head;
tail = rx_buffer_tail; tail = rx_buffer_tail;
if (head == tail) return -1; if (head == tail) {
if (++tail >= RX_BUFFER_SIZE) tail = 0; return -1;
}
if (++tail >= RX_BUFFER_SIZE) {
tail = 0;
}
out = rx_buffer[tail]; out = rx_buffer[tail];
rx_buffer_tail = tail; rx_buffer_tail = tail;
return out; return out;
@@ -284,7 +298,9 @@ int AltSoftSerial::peek(void)
head = rx_buffer_head; head = rx_buffer_head;
tail = rx_buffer_tail; tail = rx_buffer_tail;
if (head == tail) return -1; if (head == tail) {
return -1;
}
return rx_buffer[tail]; return rx_buffer[tail];
} }
@@ -294,7 +310,9 @@ int AltSoftSerial::available(void)
head = rx_buffer_head; head = rx_buffer_head;
tail = rx_buffer_tail; tail = rx_buffer_tail;
if (head >= tail) return head - tail; if (head >= tail) {
return head - tail;
}
return RX_BUFFER_SIZE + head - tail; return RX_BUFFER_SIZE + head - tail;
} }
@@ -309,9 +327,14 @@ void ftm0_isr(void)
{ {
uint32_t flags = FTM0_STATUS; uint32_t flags = FTM0_STATUS;
FTM0_STATUS = 0; FTM0_STATUS = 0;
if (flags & (1<<5)) altss_capture_interrupt(); if (flags & (1<<5)) {
if (flags & (1<<6)) altss_compare_a_interrupt(); altss_capture_interrupt();
if (flags & (1<<0)) altss_compare_b_interrupt(); }
if (flags & (1<<6)) {
altss_compare_a_interrupt();
}
if (flags & (1<<0)) {
altss_compare_b_interrupt();
}
} }
#endif #endif
+16 -8
View File
@@ -120,7 +120,9 @@ size_t EthernetClient::write(const uint8_t *buf, size_t size) {
} }
size_t EthernetClient::write(const char *str) { size_t EthernetClient::write(const char *str) {
if (str == NULL) return 0; if (str == NULL) {
return 0;
}
return write((const uint8_t *)str, strlen(str)); return write((const uint8_t *)str, strlen(str));
} }
size_t EthernetClient::write(const char *buffer, size_t size) { size_t EthernetClient::write(const char *buffer, size_t size) {
@@ -165,8 +167,9 @@ void EthernetClient::flush() {
} }
void EthernetClient::stop() { void EthernetClient::stop() {
if (_sock == -1) if (_sock == -1) {
return; return;
}
// attempt to close the connection gracefully (send a FIN to other side) // attempt to close the connection gracefully (send a FIN to other side)
shutdown(_sock, SHUT_RDWR); shutdown(_sock, SHUT_RDWR);
@@ -178,21 +181,24 @@ void EthernetClient::stop() {
uint8_t s; uint8_t s;
do { do {
s = status(); s = status();
if (s == ETHERNETCLIENT_W5100_CLOSED) if (s == ETHERNETCLIENT_W5100_CLOSED) {
break; // exit the loop break; // exit the loop
}
usleep(1000); usleep(1000);
gettimeofday(&curTime, NULL); gettimeofday(&curTime, NULL);
} while (((curTime.tv_sec - startTime.tv_sec) * 1000000) + (curTime.tv_usec - startTime.tv_usec) < 1000000); } while (((curTime.tv_sec - startTime.tv_sec) * 1000000) + (curTime.tv_usec - startTime.tv_usec) < 1000000);
// if it hasn't closed, close it forcefully // if it hasn't closed, close it forcefully
if (s != ETHERNETCLIENT_W5100_CLOSED) if (s != ETHERNETCLIENT_W5100_CLOSED) {
close(_sock); close(_sock);
}
_sock = -1; _sock = -1;
} }
uint8_t EthernetClient::status() { uint8_t EthernetClient::status() {
if (_sock == -1) return ETHERNETCLIENT_W5100_CLOSED; if (_sock == -1) {
return ETHERNETCLIENT_W5100_CLOSED;
}
struct tcp_info tcp_info; struct tcp_info tcp_info;
int tcp_info_length = sizeof(tcp_info); int tcp_info_length = sizeof(tcp_info);
@@ -227,8 +233,10 @@ uint8_t EthernetClient::status() {
} }
uint8_t EthernetClient::connected() { uint8_t EthernetClient::connected() {
if (_sock == -1) return 0; if (_sock == -1) {
return 0;
}
if (peek() < 0) { if (peek() < 0) {
if (errno == EAGAIN) { if (errno == EAGAIN) {
return 1; return 1;
+3 -1
View File
@@ -151,7 +151,9 @@ size_t EthernetServer::write(const uint8_t *buffer, size_t size)
size_t EthernetServer::write(const char *str) size_t EthernetServer::write(const char *str)
{ {
if (str == NULL) return 0; if (str == NULL) {
return 0;
}
return write((const uint8_t *)str, strlen(str)); return write((const uint8_t *)str, strlen(str));
} }
+16 -8
View File
@@ -105,10 +105,12 @@ size_t Print::print(long n, int base) {
} }
size_t Print::print(unsigned long n, int base) { size_t Print::print(unsigned long n, int base) {
if(base == 0) if(base == 0) {
return write(n); return write(n);
else }
else {
return printNumber(n, base); return printNumber(n, base);
}
} }
size_t Print::print(double n, int digits) { size_t Print::print(double n, int digits) {
@@ -182,8 +184,9 @@ size_t Print::printNumber(unsigned long n, uint8_t base) {
*str = '\0'; *str = '\0';
// prevent crash if called with base == 1 // prevent crash if called with base == 1
if(base < 2) if(base < 2) {
base = 10; base = 10;
}
do { do {
unsigned long m = n; unsigned long m = n;
@@ -198,14 +201,18 @@ size_t Print::printNumber(unsigned long n, uint8_t base) {
size_t Print::printFloat(double number, uint8_t digits) { size_t Print::printFloat(double number, uint8_t digits) {
size_t n = 0; size_t n = 0;
if(std::isnan(number)) if(std::isnan(number)) {
return print("nan"); return print("nan");
if(std::isinf(number)) }
if(std::isinf(number)) {
return print("inf"); return print("inf");
if(number > 4294967040.0) }
if(number > 4294967040.0) {
return print("ovf"); // constant determined empirically return print("ovf"); // constant determined empirically
if(number < -4294967040.0) }
if(number < -4294967040.0) {
return print("ovf"); // constant determined empirically return print("ovf"); // constant determined empirically
}
// Handle negative numbers // Handle negative numbers
if(number < 0.0) { if(number < 0.0) {
@@ -215,8 +222,9 @@ size_t Print::printFloat(double number, uint8_t digits) {
// Round correctly so that print(1.999, 2) prints as "2.00" // Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5; double rounding = 0.5;
for(uint8_t i = 0; i < digits; ++i) for(uint8_t i = 0; i < digits; ++i) {
rounding /= 10.0; rounding /= 10.0;
}
number += rounding; number += rounding;
+3 -1
View File
@@ -212,7 +212,9 @@ int SerialPort::peek()
{ {
FILE * f = fdopen(sd, "r+"); FILE * f = fdopen(sd, "r+");
int c = getc(f); int c = getc(f);
if (c == EOF) return -1; if (c == EOF) {
return -1;
}
ungetc(c, f); ungetc(c, f);
return c; return c;
} }
+53 -29
View File
@@ -33,8 +33,9 @@ int Stream::timedRead() {
_startMillis = millis(); _startMillis = millis();
do { do {
c = read(); c = read();
if(c >= 0) if(c >= 0) {
return c; return c;
}
yield(); yield();
} while(millis() - _startMillis < _timeout); } while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
@@ -46,8 +47,9 @@ int Stream::timedPeek() {
_startMillis = millis(); _startMillis = millis();
do { do {
c = peek(); c = peek();
if(c >= 0) if(c >= 0) {
return c; return c;
}
yield(); yield();
} while(millis() - _startMillis < _timeout); } while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout return -1; // -1 indicates timeout
@@ -59,12 +61,15 @@ int Stream::peekNextDigit() {
int c; int c;
while(1) { while(1) {
c = timedPeek(); c = timedPeek();
if(c < 0) if(c < 0) {
return c; // timeout return c; // timeout
if(c == '-') }
if(c == '-') {
return c; return c;
if(c >= '0' && c <= '9') }
if(c >= '0' && c <= '9') {
return c; return c;
}
read(); // discard non-numeric read(); // discard non-numeric
} }
} }
@@ -101,13 +106,14 @@ bool Stream::findUntil(const char *target, size_t targetLen, const char *termina
size_t termIndex = 0; size_t termIndex = 0;
int c; int c;
if(*target == 0) if(*target == 0) {
return true; // return true if target is a null string return true; // return true if target is a null string
}
while((c = timedRead()) > 0) { while((c = timedRead()) > 0) {
if(c != target[index]) if(c != target[index]) {
index = 0; // reset index if any char does not match index = 0; // reset index if any char does not match
}
if(c == target[index]) { if(c == target[index]) {
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1); //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if(++index >= targetLen) { // return true if all chars in the target match if(++index >= targetLen) { // return true if all chars in the target match
@@ -116,10 +122,12 @@ bool Stream::findUntil(const char *target, size_t targetLen, const char *termina
} }
if(termLen > 0 && c == terminator[termIndex]) { if(termLen > 0 && c == terminator[termIndex]) {
if(++termIndex >= termLen) if(++termIndex >= termLen) {
return false; // return false if terminate string found before target string return false; // return false if terminate string found before target string
} else }
} else {
termIndex = 0; termIndex = 0;
}
} }
return false; return false;
} }
@@ -140,22 +148,27 @@ long Stream::parseInt(char skipChar) {
c = peekNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if(c < 0) if(c < 0) {
return 0; // zero returned if timeout return 0; // zero returned if timeout
}
do { do {
if(c == skipChar) if(c == skipChar) {
; // ignore this charactor // ignore this charactor
else if(c == '-') }
else if(c == '-') {
isNegative = true; isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit? }
else if(c >= '0' && c <= '9') { // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
}
read(); // consume the character we got with peek read(); // consume the character we got with peek
c = timedPeek(); c = timedPeek();
} while((c >= '0' && c <= '9') || c == skipChar); } while((c >= '0' && c <= '9') || c == skipChar);
if(isNegative) if(isNegative) {
value = -value; value = -value;
}
return value; return value;
} }
@@ -175,31 +188,39 @@ float Stream::parseFloat(char skipChar) {
c = peekNextDigit(); c = peekNextDigit();
// ignore non numeric leading characters // ignore non numeric leading characters
if(c < 0) if(c < 0) {
return 0; // zero returned if timeout return 0; // zero returned if timeout
}
do { do {
if(c == skipChar) if(c == skipChar) {
; // ignore // ignore
else if(c == '-') }
else if(c == '-') {
isNegative = true; isNegative = true;
else if(c == '.') }
else if(c == '.') {
isFraction = true; isFraction = true;
}
else if(c >= '0' && c <= '9') { // is c a digit? else if(c >= '0' && c <= '9') { // is c a digit?
value = value * 10 + c - '0'; value = value * 10 + c - '0';
if(isFraction) if(isFraction) {
fraction *= 0.1; fraction *= 0.1;
}
} }
read(); // consume the character we got with peek read(); // consume the character we got with peek
c = timedPeek(); c = timedPeek();
} while((c >= '0' && c <= '9') || c == '.' || c == skipChar); } while((c >= '0' && c <= '9') || c == '.' || c == skipChar);
if(isNegative) if(isNegative) {
value = -value; value = -value;
if(isFraction) }
if(isFraction) {
return value * fraction; return value * fraction;
else }
else {
return value; return value;
}
} }
// read characters from stream into buffer // read characters from stream into buffer
@@ -211,8 +232,9 @@ size_t Stream::readBytes(char *buffer, size_t length) {
size_t count = 0; size_t count = 0;
while(count < length) { while(count < length) {
int c = timedRead(); int c = timedRead();
if(c < 0) if(c < 0) {
break; break;
}
*buffer++ = (char) c; *buffer++ = (char) c;
count++; count++;
} }
@@ -224,13 +246,15 @@ size_t Stream::readBytes(char *buffer, size_t length) {
// returns the number of characters placed in the buffer (0 means no valid data found) // returns the number of characters placed in the buffer (0 means no valid data found)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) { size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length) {
if(length < 1) if(length < 1) {
return 0; return 0;
}
size_t index = 0; size_t index = 0;
while(index < length) { while(index < length) {
int c = timedRead(); int c = timedRead();
if(c < 0 || c == terminator) if(c < 0 || c == terminator) {
break; break;
}
*buffer++ = (char) c; *buffer++ = (char) c;
index++; index++;
} }
+6 -4
View File
@@ -1,14 +1,14 @@
/* /*
noniso.cpp - replacements for non-ISO functions used by Arduino core noniso.cpp - replacements for non-ISO functions used by Arduino core
Copyright © 2016 Ivan Grokhotkov Copyright © 2016 Ivan Grokhotkov
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
@@ -61,8 +61,9 @@ char* itoa(int value, char* result, int base) {
} while(quotient); } while(quotient);
// Apply negative sign // Apply negative sign
if(value < 0) if(value < 0) {
*out++ = '-'; *out++ = '-';
}
reverse(result, out); reverse(result, out);
*out = 0; *out = 0;
@@ -112,8 +113,9 @@ char* ltoa(long value, char* result, int base) {
} while(quotient); } while(quotient);
// Apply negative sign // Apply negative sign
if(value < 0) if(value < 0) {
*out++ = '-'; *out++ = '-';
}
reverse(result, out); reverse(result, out);
*out = 0; *out = 0;
+15 -5
View File
@@ -231,7 +231,9 @@ boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){
uint16_t PubSubClient::readPacket(uint8_t* lengthLength) { uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
uint16_t len = 0; uint16_t len = 0;
if(!readByte(buffer, &len)) return 0; if(!readByte(buffer, &len)) {
return 0;
}
bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH; bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH;
uint32_t multiplier = 1; uint32_t multiplier = 1;
uint16_t length = 0; uint16_t length = 0;
@@ -240,7 +242,9 @@ uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
uint8_t start = 0; uint8_t start = 0;
do { do {
if(!readByte(&digit)) return 0; if(!readByte(&digit)) {
return 0;
}
buffer[len++] = digit; buffer[len++] = digit;
length += (digit & 127) * multiplier; length += (digit & 127) * multiplier;
multiplier *= 128; multiplier *= 128;
@@ -249,8 +253,12 @@ uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
if (isPublish) { if (isPublish) {
// Read in topic length to calculate bytes to skip over for Stream writing // Read in topic length to calculate bytes to skip over for Stream writing
if(!readByte(buffer, &len)) return 0; if(!readByte(buffer, &len)) {
if(!readByte(buffer, &len)) return 0; return 0;
}
if(!readByte(buffer, &len)) {
return 0;
}
skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2]; skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2];
start = 2; start = 2;
if (buffer[0]&MQTTQOS1) { if (buffer[0]&MQTTQOS1) {
@@ -260,7 +268,9 @@ uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
} }
for (uint16_t i = start;i<length;i++) { for (uint16_t i = start;i<length;i++) {
if(!readByte(&digit)) return 0; if(!readByte(&digit)) {
return 0;
}
if (this->stream) { if (this->stream) {
if (isPublish && len-*lengthLength-2>skip) { if (isPublish && len-*lengthLength-2>skip) {
this->stream->write(digit); this->stream->write(digit);
+18 -15
View File
@@ -71,7 +71,7 @@ LOCAL uint8_t RF24_spiMultiByteTransfer(uint8_t cmd, uint8_t* buf, uint8_t len,
} else { } else {
status = *prx++; // status is 1st byte of receive buffer status = *prx++; // status is 1st byte of receive buffer
// decrement before to skip status byte // decrement before to skip status byte
while (--size) { *buf++ = *prx++; } while (--size) { *buf++ = *prx++; }
} }
} else { } else {
status = *prx; // status is 1st byte of receive buffer status = *prx; // status is 1st byte of receive buffer
@@ -79,9 +79,11 @@ LOCAL uint8_t RF24_spiMultiByteTransfer(uint8_t cmd, uint8_t* buf, uint8_t len,
#else #else
status = _SPI.transfer( cmd ); status = _SPI.transfer( cmd );
while ( len-- ) { while ( len-- ) {
if (aReadMode) { if (aReadMode) {
status = _SPI.transfer( NOP ); status = _SPI.transfer( NOP );
if (buf != NULL) *current++ = status; if (buf != NULL) {
*current++ = status;
}
} else status = _SPI.transfer(*current++); } else status = _SPI.transfer(*current++);
} }
#endif #endif
@@ -92,7 +94,7 @@ LOCAL uint8_t RF24_spiMultiByteTransfer(uint8_t cmd, uint8_t* buf, uint8_t len,
// timing // timing
delayMicroseconds(10); delayMicroseconds(10);
return status; return status;
} }
LOCAL uint8_t RF24_spiByteTransfer(uint8_t cmd) { LOCAL uint8_t RF24_spiByteTransfer(uint8_t cmd) {
return RF24_spiMultiByteTransfer( cmd, NULL, 0, false); return RF24_spiMultiByteTransfer( cmd, NULL, 0, false);
@@ -182,8 +184,8 @@ LOCAL void RF24_enableFeatures(void) {
RF24_RAW_writeByteRegister(ACTIVATE, 0x73); RF24_RAW_writeByteRegister(ACTIVATE, 0x73);
} }
LOCAL void RF24_openWritingPipe(uint8_t recipient) { LOCAL void RF24_openWritingPipe(uint8_t recipient) {
RF24_DEBUG(PSTR("RF24:open writing pipe, recipient=%d\n"), recipient); RF24_DEBUG(PSTR("RF24:open writing pipe, recipient=%d\n"), recipient);
// only write LSB of RX0 and TX pipe // only write LSB of RX0 and TX pipe
RF24_setPipeLSB(RX_ADDR_P0, recipient); RF24_setPipeLSB(RX_ADDR_P0, recipient);
RF24_setPipeLSB(TX_ADDR, recipient); RF24_setPipeLSB(TX_ADDR, recipient);
@@ -191,10 +193,12 @@ LOCAL void RF24_openWritingPipe(uint8_t recipient) {
LOCAL void RF24_startListening(void) { LOCAL void RF24_startListening(void) {
RF24_DEBUG(PSTR("RF24:start listening\n")); RF24_DEBUG(PSTR("RF24:start listening\n"));
// toggle PRX // toggle PRX
RF24_setRFConfiguration(MY_RF24_CONFIGURATION | _BV(PWR_UP) | _BV(PRIM_RX) ); RF24_setRFConfiguration(MY_RF24_CONFIGURATION | _BV(PWR_UP) | _BV(PRIM_RX) );
// all RX pipe addresses must be unique, therefore skip if node ID is 0xFF // all RX pipe addresses must be unique, therefore skip if node ID is 0xFF
if(MY_RF24_NODE_ADDRESS!=AUTO) RF24_setPipeLSB(RX_ADDR_P0, MY_RF24_NODE_ADDRESS); if(MY_RF24_NODE_ADDRESS!=AUTO) {
RF24_setPipeLSB(RX_ADDR_P0, MY_RF24_NODE_ADDRESS);
}
// start listening // start listening
RF24_ce(HIGH); RF24_ce(HIGH);
} }
@@ -219,7 +223,7 @@ LOCAL bool RF24_sendMessage( uint8_t recipient, const void* buf, uint8_t len ) {
uint8_t status; uint8_t status;
RF24_stopListening(); RF24_stopListening();
RF24_openWritingPipe( recipient ); RF24_openWritingPipe( recipient );
RF24_DEBUG(PSTR("RF24:send message to %d, len=%d\n"),recipient,len); RF24_DEBUG(PSTR("RF24:send message to %d, len=%d\n"),recipient,len);
// flush TX FIFO // flush TX FIFO
RF24_flushTX(); RF24_flushTX();
@@ -251,10 +255,10 @@ LOCAL bool RF24_sendMessage( uint8_t recipient, const void* buf, uint8_t len ) {
LOCAL uint8_t RF24_getDynamicPayloadSize(void) { LOCAL uint8_t RF24_getDynamicPayloadSize(void) {
uint8_t result = RF24_spiMultiByteTransfer(R_RX_PL_WID, NULL, 1, true); uint8_t result = RF24_spiMultiByteTransfer(R_RX_PL_WID, NULL, 1, true);
// check if payload size invalid // check if payload size invalid
if(result > 32) { if(result > 32) {
RF24_DEBUG(PSTR("RF24:invalid payload length = %d\n"),result); RF24_DEBUG(PSTR("RF24:invalid payload length = %d\n"),result);
RF24_flushRX(); RF24_flushRX();
result = 0; result = 0;
} }
return result; return result;
} }
@@ -267,7 +271,7 @@ LOCAL bool RF24_isDataAvailable() {
LOCAL uint8_t RF24_readMessage( void* buf) { LOCAL uint8_t RF24_readMessage( void* buf) {
const uint8_t len = RF24_getDynamicPayloadSize(); const uint8_t len = RF24_getDynamicPayloadSize();
RF24_DEBUG(PSTR("RF24:read message, len=%d\n"), len); RF24_DEBUG(PSTR("RF24:read message, len=%d\n"), len);
RF24_spiMultiByteTransfer( R_RX_PAYLOAD , (uint8_t*)buf, len, true ); RF24_spiMultiByteTransfer( R_RX_PAYLOAD , (uint8_t*)buf, len, true );
// clear RX interrupt // clear RX interrupt
RF24_setStatus(_BV(RX_DR) ); RF24_setStatus(_BV(RX_DR) );
return len; return len;
@@ -314,7 +318,7 @@ LOCAL void RF24_irqHandler( void )
// for a message we've already read. // for a message we've already read.
while (RF24_isDataAvailable()) { while (RF24_isDataAvailable()) {
RF24_receiveCallback(); // Must call RF24_readMessage(), which will clear RX_DR IRQ ! RF24_receiveCallback(); // Must call RF24_readMessage(), which will clear RX_DR IRQ !
} }
// Restore our interrupt handler. // Restore our interrupt handler.
#if defined(MY_GATEWAY_SERIAL) && !defined(__linux__) #if defined(MY_GATEWAY_SERIAL) && !defined(__linux__)
noInterrupts(); noInterrupts();
@@ -395,4 +399,3 @@ LOCAL bool RF24_initialize(void) {
RF24_setStatus(_BV(TX_DS) | _BV(MAX_RT) | _BV(RX_DR)); RF24_setStatus(_BV(TX_DS) | _BV(MAX_RT) | _BV(RX_DR));
return true; return true;
} }
+96 -71
View File
@@ -6,23 +6,23 @@
// ********************************************************************************** // **********************************************************************************
// License // License
// ********************************************************************************** // **********************************************************************************
// This program is free software; you can redistribute it // This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU General // and/or modify it under the terms of the GNU General
// Public License as published by the Free Software // Public License as published by the Free Software
// Foundation; either version 3 of the License, or // Foundation; either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will // This program is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY; without even the // be useful, but WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A // implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE. See the GNU General Public // PARTICULAR PURPOSE. See the GNU General Public
// License for more details. // License for more details.
// //
// You should have received a copy of the GNU General // You should have received a copy of the GNU General
// Public License along with this program. // Public License along with this program.
// If not, see <http://www.gnu.org/licenses/>. // If not, see <http://www.gnu.org/licenses/>.
// //
// Licence can be viewed at // Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt // http://www.gnu.org/licenses/gpl-3.0.txt
// //
// Please maintain this license information along with authorship // Please maintain this license information along with authorship
@@ -93,17 +93,18 @@ bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)
unsigned long start = millis(); unsigned long start = millis();
uint8_t timeout = 50; uint8_t timeout = 50;
do { do {
writeReg(REG_SYNCVALUE1, 0xAA); writeReg(REG_SYNCVALUE1, 0xAA);
yield(); yield();
} while (readReg(REG_SYNCVALUE1) != 0xaa && millis()-start < timeout); } while (readReg(REG_SYNCVALUE1) != 0xaa && millis()-start < timeout);
start = millis(); start = millis();
do { do {
writeReg(REG_SYNCVALUE1, 0x55); writeReg(REG_SYNCVALUE1, 0x55);
yield(); yield();
} while (readReg(REG_SYNCVALUE1) != 0x55 && millis()-start < timeout); } while (readReg(REG_SYNCVALUE1) != 0x55 && millis()-start < timeout);
for (uint8_t i = 0; CONFIG[i][0] != 255; i++) for (uint8_t i = 0; CONFIG[i][0] != 255; i++) {
writeReg(CONFIG[i][0], CONFIG[i][1]); writeReg(CONFIG[i][0], CONFIG[i][1]);
}
// Encryption is persistent between resets and can trip you up during debugging. // Encryption is persistent between resets and can trip you up during debugging.
// Disable it during initialization so we always start from a known state. // Disable it during initialization so we always start from a known state.
@@ -113,10 +114,11 @@ bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)
setMode(RF69_MODE_STANDBY); setMode(RF69_MODE_STANDBY);
start = millis(); start = millis();
while (((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00) && millis()-start < timeout) { while (((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00) && millis()-start < timeout) {
yield(); yield();
} // wait for ModeReady } // wait for ModeReady
if (millis()-start >= timeout) if (millis()-start >= timeout) {
return false; return false;
}
attachInterrupt(_interruptNum, RFM69::isr0, RISING); attachInterrupt(_interruptNum, RFM69::isr0, RISING);
selfPointer = this; selfPointer = this;
@@ -149,17 +151,22 @@ void RFM69::setFrequency(uint32_t freqHz)
void RFM69::setMode(uint8_t newMode) void RFM69::setMode(uint8_t newMode)
{ {
if (newMode == _mode) if (newMode == _mode) {
return; return;
}
switch (newMode) { switch (newMode) {
case RF69_MODE_TX: case RF69_MODE_TX:
writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_TRANSMITTER); writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_TRANSMITTER);
if (_isRFM69HW) setHighPowerRegs(true); if (_isRFM69HW) {
setHighPowerRegs(true);
}
break; break;
case RF69_MODE_RX: case RF69_MODE_RX:
writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER); writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER);
if (_isRFM69HW) setHighPowerRegs(false); if (_isRFM69HW) {
setHighPowerRegs(false);
}
break; break;
case RF69_MODE_SYNTH: case RF69_MODE_SYNTH:
writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SYNTHESIZER); writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SYNTHESIZER);
@@ -209,7 +216,9 @@ void RFM69::setNetwork(uint8_t networkID)
void RFM69::setPowerLevel(uint8_t powerLevel) void RFM69::setPowerLevel(uint8_t powerLevel)
{ {
_powerLevel = (powerLevel > 31 ? 31 : powerLevel); _powerLevel = (powerLevel > 31 ? 31 : powerLevel);
if (_isRFM69HW) _powerLevel /= 2; if (_isRFM69HW) {
_powerLevel /= 2;
}
writeReg(REG_PALEVEL, (readReg(REG_PALEVEL) & 0xE0) | _powerLevel); writeReg(REG_PALEVEL, (readReg(REG_PALEVEL) & 0xE0) | _powerLevel);
} }
@@ -227,7 +236,9 @@ void RFM69::send(uint8_t toAddress, const void* buffer, uint8_t bufferSize, bool
{ {
writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks
uint32_t now = millis(); uint32_t now = millis();
while (!canSend() && millis() - now < RF69_CSMA_LIMIT_MS) receiveDone(); while (!canSend() && millis() - now < RF69_CSMA_LIMIT_MS) {
receiveDone();
}
sendFrame(toAddress, buffer, bufferSize, requestACK, false); sendFrame(toAddress, buffer, bufferSize, requestACK, false);
} }
@@ -258,8 +269,9 @@ bool RFM69::sendWithRetry(uint8_t toAddress, const void* buffer, uint8_t bufferS
// should be polled immediately after sending a packet with ACK request // should be polled immediately after sending a packet with ACK request
bool RFM69::ACKReceived(uint8_t fromNodeID) { bool RFM69::ACKReceived(uint8_t fromNodeID) {
if (receiveDone()) if (receiveDone()) {
return (SENDERID == fromNodeID || fromNodeID == RF69_BROADCAST_ADDR) && ACK_RECEIVED; return (SENDERID == fromNodeID || fromNodeID == RF69_BROADCAST_ADDR) && ACK_RECEIVED;
}
return false; return false;
} }
@@ -287,21 +299,25 @@ void RFM69::sendACK(const void* buffer, uint8_t bufferSize) {
void RFM69::interruptHook(uint8_t CTLbyte) { void RFM69::interruptHook(uint8_t CTLbyte) {
(void)CTLbyte; (void)CTLbyte;
}; };
// internal function // internal function
void RFM69::sendFrame(uint8_t toAddress, const void* buffer, uint8_t bufferSize, bool requestACK, bool sendACK) void RFM69::sendFrame(uint8_t toAddress, const void* buffer, uint8_t bufferSize, bool requestACK, bool sendACK)
{ {
setMode(RF69_MODE_STANDBY); // turn off receiver to prevent reception while filling fifo setMode(RF69_MODE_STANDBY); // turn off receiver to prevent reception while filling fifo
while ((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // wait for ModeReady while ((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00) {} // wait for ModeReady
writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00); // DIO0 is "Packet Sent" writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00); // DIO0 is "Packet Sent"
if (bufferSize > RF69_MAX_DATA_LEN) bufferSize = RF69_MAX_DATA_LEN; if (bufferSize > RF69_MAX_DATA_LEN) {
bufferSize = RF69_MAX_DATA_LEN;
}
// control byte // control byte
uint8_t CTLbyte = 0x00; uint8_t CTLbyte = 0x00;
if (sendACK) if (sendACK) {
CTLbyte = RFM69_CTL_SENDACK; CTLbyte = RFM69_CTL_SENDACK;
else if (requestACK) }
else if (requestACK) {
CTLbyte = RFM69_CTL_REQACK; CTLbyte = RFM69_CTL_REQACK;
}
// write to FIFO // write to FIFO
select(); select();
@@ -311,14 +327,15 @@ void RFM69::sendFrame(uint8_t toAddress, const void* buffer, uint8_t bufferSize,
SPI.transfer(_address); SPI.transfer(_address);
SPI.transfer(CTLbyte); SPI.transfer(CTLbyte);
for (uint8_t i = 0; i < bufferSize; i++) for (uint8_t i = 0; i < bufferSize; i++) {
SPI.transfer(((uint8_t*) buffer)[i]); SPI.transfer(((uint8_t*) buffer)[i]);
}
unselect(); unselect();
// no need to wait for transmit mode to be ready since its handled by the radio // no need to wait for transmit mode to be ready since its handled by the radio
setMode(RF69_MODE_TX); setMode(RF69_MODE_TX);
uint32_t txStart = millis(); uint32_t txStart = millis();
while (hwDigitalRead(_interruptPin) == 0 && millis() - txStart < RF69_TX_LIMIT_MS); // wait for DIO0 to turn HIGH signalling transmission finish while (hwDigitalRead(_interruptPin) == 0 && millis() - txStart < RF69_TX_LIMIT_MS) {} // wait for DIO0 to turn HIGH signalling transmission finish
//while (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PACKETSENT == 0x00); // wait for ModeReady //while (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PACKETSENT == 0x00); // wait for ModeReady
setMode(RF69_MODE_STANDBY); setMode(RF69_MODE_STANDBY);
} }
@@ -352,14 +369,16 @@ void RFM69::interruptHandler() {
ACK_RECEIVED = CTLbyte & RFM69_CTL_SENDACK; // extract ACK-received flag ACK_RECEIVED = CTLbyte & RFM69_CTL_SENDACK; // extract ACK-received flag
ACK_REQUESTED = CTLbyte & RFM69_CTL_REQACK; // extract ACK-requested flag ACK_REQUESTED = CTLbyte & RFM69_CTL_REQACK; // extract ACK-requested flag
interruptHook(CTLbyte); // TWS: hook to derived class interrupt function interruptHook(CTLbyte); // TWS: hook to derived class interrupt function
for (uint8_t i = 0; i < DATALEN; i++) for (uint8_t i = 0; i < DATALEN; i++)
{ {
DATA[i] = SPI.transfer(0); DATA[i] = SPI.transfer(0);
} }
if (DATALEN < RF69_MAX_DATA_LEN) DATA[DATALEN] = 0; // add null at end of string if (DATALEN < RF69_MAX_DATA_LEN) {
DATA[DATALEN] = 0; // add null at end of string
}
unselect(); unselect();
setMode(RF69_MODE_RX); setMode(RF69_MODE_RX);
} }
@@ -379,8 +398,9 @@ void RFM69::receiveBegin() {
ACK_REQUESTED = 0; ACK_REQUESTED = 0;
ACK_RECEIVED = 0; ACK_RECEIVED = 0;
RSSI = 0; RSSI = 0;
if (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY) if (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY) {
writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks
}
writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01); // set DIO0 to "PAYLOADREADY" in receive mode writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01); // set DIO0 to "PAYLOADREADY" in receive mode
setMode(RF69_MODE_RX); setMode(RF69_MODE_RX);
} }
@@ -414,8 +434,9 @@ void RFM69::encrypt(const char* key) {
{ {
select(); select();
SPI.transfer(REG_AESKEY1 | 0x80); SPI.transfer(REG_AESKEY1 | 0x80);
for (uint8_t i = 0; i < 16; i++) for (uint8_t i = 0; i < 16; i++) {
SPI.transfer(key[i]); SPI.transfer(key[i]);
}
unselect(); unselect();
} }
writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFE) | (key ? 1 : 0)); writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFE) | (key ? 1 : 0));
@@ -428,7 +449,7 @@ int16_t RFM69::readRSSI(bool forceTrigger) {
{ {
// RSSI trigger not needed if DAGC is in continuous mode // RSSI trigger not needed if DAGC is in continuous mode
writeReg(REG_RSSICONFIG, RF_RSSI_START); writeReg(REG_RSSICONFIG, RF_RSSI_START);
while ((readReg(REG_RSSICONFIG) & RF_RSSI_DONE) == 0x00); // wait for RSSI_Ready while ((readReg(REG_RSSICONFIG) & RF_RSSI_DONE) == 0x00) {} // wait for RSSI_Ready
} }
rssi = -readReg(REG_RSSIVALUE); rssi = -readReg(REG_RSSIVALUE);
rssi >>= 1; rssi >>= 1;
@@ -489,10 +510,12 @@ void RFM69::promiscuous(bool onOff) {
void RFM69::setHighPower(bool onOff) { void RFM69::setHighPower(bool onOff) {
_isRFM69HW = onOff; _isRFM69HW = onOff;
writeReg(REG_OCP, _isRFM69HW ? RF_OCP_OFF : RF_OCP_ON); writeReg(REG_OCP, _isRFM69HW ? RF_OCP_OFF : RF_OCP_ON);
if (_isRFM69HW) // turning ON if (_isRFM69HW) { // turning ON
writeReg(REG_PALEVEL, (readReg(REG_PALEVEL) & 0x1F) | RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON); // enable P1 & P2 amplifier stages writeReg(REG_PALEVEL, (readReg(REG_PALEVEL) & 0x1F) | RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON); // enable P1 & P2 amplifier stages
else }
else {
writeReg(REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | _powerLevel); // enable P0 only writeReg(REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | _powerLevel); // enable P0 only
}
} }
// internal function // internal function
@@ -501,7 +524,7 @@ void RFM69::setHighPowerRegs(bool onOff) {
writeReg(REG_TESTPA2, onOff ? 0x7C : 0x70); writeReg(REG_TESTPA2, onOff ? 0x7C : 0x70);
} }
// set the slave select (CS) pin // set the slave select (CS) pin
void RFM69::setCS(uint8_t newSPISlaveSelect) { void RFM69::setCS(uint8_t newSPISlaveSelect) {
_slaveSelectPin = newSPISlaveSelect; _slaveSelectPin = newSPISlaveSelect;
hwDigitalWrite(_slaveSelectPin, HIGH); hwDigitalWrite(_slaveSelectPin, HIGH);
@@ -519,7 +542,9 @@ void SerialWrite ( uint8_t c ) {
} }
void SerialPrint_P(PGM_P str, void (*f)(uint8_t) = SerialWrite ) { void SerialPrint_P(PGM_P str, void (*f)(uint8_t) = SerialWrite ) {
for (uint8_t c; (c = pgm_read_byte(str)); str++) (*f)(c); for (uint8_t c; (c = pgm_read_byte(str)); str++) {
(*f)(c);
}
} }
#endif #endif
@@ -527,7 +552,7 @@ void RFM69::readAllRegs()
{ {
uint8_t regVal; uint8_t regVal;
#if REGISTER_DETAIL #if REGISTER_DETAIL
int capVal; int capVal;
//... State Variables for intelligent decoding //... State Variables for intelligent decoding
@@ -536,7 +561,7 @@ void RFM69::readAllRegs()
int freqDev = 0; int freqDev = 0;
long freqCenter = 0; long freqCenter = 0;
#endif #endif
Serial.println("Address - HEX - BIN"); Serial.println("Address - HEX - BIN");
for (uint8_t regAddr = 1; regAddr <= 0x4F; regAddr++) for (uint8_t regAddr = 1; regAddr <= 0x4F; regAddr++)
{ {
@@ -551,8 +576,8 @@ void RFM69::readAllRegs()
Serial.print(" - "); Serial.print(" - ");
Serial.println(regVal,BIN); Serial.println(regVal,BIN);
#if REGISTER_DETAIL #if REGISTER_DETAIL
switch ( regAddr ) switch ( regAddr )
{ {
case 0x1 : { case 0x1 : {
SerialPrint ( "Controls the automatic Sequencer ( see section 4.2 )\nSequencerOff : " ); SerialPrint ( "Controls the automatic Sequencer ( see section 4.2 )\nSequencerOff : " );
@@ -561,19 +586,19 @@ void RFM69::readAllRegs()
} else { } else {
SerialPrint ( "0 -> Operating mode as selected with Mode bits in RegOpMode is automatically reached with the Sequencer\n" ); SerialPrint ( "0 -> Operating mode as selected with Mode bits in RegOpMode is automatically reached with the Sequencer\n" );
} }
SerialPrint( "\nEnables Listen mode, should be enabled whilst in Standby mode:\nListenOn : " ); SerialPrint( "\nEnables Listen mode, should be enabled whilst in Standby mode:\nListenOn : " );
if ( 0x40 & regVal ) { if ( 0x40 & regVal ) {
SerialPrint ( "1 -> On\n" ); SerialPrint ( "1 -> On\n" );
} else { } else {
SerialPrint ( "0 -> Off ( see section 4.3)\n" ); SerialPrint ( "0 -> Off ( see section 4.3)\n" );
} }
SerialPrint( "\nAborts Listen mode when set together with ListenOn=0 See section 4.3.4 for details (Always reads 0.)\n" ); SerialPrint( "\nAborts Listen mode when set together with ListenOn=0 See section 4.3.4 for details (Always reads 0.)\n" );
if ( 0x20 & regVal ) { if ( 0x20 & regVal ) {
SerialPrint ( "ERROR - ListenAbort should NEVER return 1 this is a write only register\n" ); SerialPrint ( "ERROR - ListenAbort should NEVER return 1 this is a write only register\n" );
} }
SerialPrint("\nTransceiver's operating modes:\nMode : "); SerialPrint("\nTransceiver's operating modes:\nMode : ");
capVal = (regVal >> 2) & 0x7; capVal = (regVal >> 2) & 0x7;
if ( capVal == 0b000 ) { if ( capVal == 0b000 ) {
@@ -593,9 +618,9 @@ void RFM69::readAllRegs()
SerialPrint ( "\n" ); SerialPrint ( "\n" );
break; break;
} }
case 0x2 : { case 0x2 : {
SerialPrint("Data Processing mode:\nDataMode : "); SerialPrint("Data Processing mode:\nDataMode : ");
capVal = (regVal >> 5) & 0x3; capVal = (regVal >> 5) & 0x3;
if ( capVal == 0b00 ) { if ( capVal == 0b00 ) {
@@ -607,7 +632,7 @@ void RFM69::readAllRegs()
} else if ( capVal == 0b11 ) { } else if ( capVal == 0b11 ) {
SerialPrint ( "11 -> Continuous mode without bit synchronizer\n" ); SerialPrint ( "11 -> Continuous mode without bit synchronizer\n" );
} }
SerialPrint("\nModulation scheme:\nModulation Type : "); SerialPrint("\nModulation scheme:\nModulation Type : ");
capVal = (regVal >> 3) & 0x3; capVal = (regVal >> 3) & 0x3;
if ( capVal == 0b00 ) { if ( capVal == 0b00 ) {
@@ -620,7 +645,7 @@ void RFM69::readAllRegs()
} else if ( capVal == 0b11 ) { } else if ( capVal == 0b11 ) {
SerialPrint ( "11 -> reserved\n" ); SerialPrint ( "11 -> reserved\n" );
} }
SerialPrint("\nData shaping: "); SerialPrint("\nData shaping: ");
if ( modeFSK ) { if ( modeFSK ) {
SerialPrint( "in FSK:\n" ); SerialPrint( "in FSK:\n" );
@@ -650,16 +675,16 @@ void RFM69::readAllRegs()
SerialPrint ( "ERROR - 11 is reserved\n" ); SerialPrint ( "ERROR - 11 is reserved\n" );
} }
} }
SerialPrint ( "\n" ); SerialPrint ( "\n" );
break; break;
} }
case 0x3 : { case 0x3 : {
bitRate = (regVal << 8); bitRate = (regVal << 8);
break; break;
} }
case 0x4 : { case 0x4 : {
bitRate |= regVal; bitRate |= regVal;
SerialPrint ( "Bit Rate (Chip Rate when Manchester encoding is enabled)\nBitRate : "); SerialPrint ( "Bit Rate (Chip Rate when Manchester encoding is enabled)\nBitRate : ");
@@ -668,12 +693,12 @@ void RFM69::readAllRegs()
SerialPrint( "\n" ); SerialPrint( "\n" );
break; break;
} }
case 0x5 : { case 0x5 : {
freqDev = ( (regVal & 0x3f) << 8 ); freqDev = ( (regVal & 0x3f) << 8 );
break; break;
} }
case 0x6 : { case 0x6 : {
freqDev |= regVal; freqDev |= regVal;
SerialPrint( "Frequency deviation\nFdev : " ); SerialPrint( "Frequency deviation\nFdev : " );
@@ -682,20 +707,20 @@ void RFM69::readAllRegs()
SerialPrint ( "\n" ); SerialPrint ( "\n" );
break; break;
} }
case 0x7 : { case 0x7 : {
unsigned long tempVal = regVal; unsigned long tempVal = regVal;
freqCenter = ( tempVal << 16 ); freqCenter = ( tempVal << 16 );
break; break;
} }
case 0x8 : { case 0x8 : {
unsigned long tempVal = regVal; unsigned long tempVal = regVal;
freqCenter = freqCenter | ( tempVal << 8 ); freqCenter = freqCenter | ( tempVal << 8 );
break; break;
} }
case 0x9 : { case 0x9 : {
freqCenter = freqCenter | regVal; freqCenter = freqCenter | regVal;
SerialPrint ( "RF Carrier frequency\nFRF : " ); SerialPrint ( "RF Carrier frequency\nFRF : " );
unsigned long val = 61UL * freqCenter; unsigned long val = 61UL * freqCenter;
@@ -711,7 +736,7 @@ void RFM69::readAllRegs()
} else { } else {
SerialPrint ( "0 -> RC calibration is in progress\n" ); SerialPrint ( "0 -> RC calibration is in progress\n" );
} }
SerialPrint ( "\n" ); SerialPrint ( "\n" );
break; break;
} }
@@ -726,7 +751,7 @@ void RFM69::readAllRegs()
SerialPrint ( "\n" ); SerialPrint ( "\n" );
break; break;
} }
case 0xc : { case 0xc : {
SerialPrint ( "Reserved\n\n" ); SerialPrint ( "Reserved\n\n" );
break; break;
@@ -745,7 +770,7 @@ void RFM69::readAllRegs()
} else if ( val == 0b11 ) { } else if ( val == 0b11 ) {
SerialPrint ( "11 -> 262 ms\n" ); SerialPrint ( "11 -> 262 ms\n" );
} }
SerialPrint ( "\nResolution of Listen mode Rx time (calibrated RC osc):\nListenResolRx : " ); SerialPrint ( "\nResolution of Listen mode Rx time (calibrated RC osc):\nListenResolRx : " );
val = (regVal >> 4) & 0x3; val = (regVal >> 4) & 0x3;
if ( val == 0b00 ) { if ( val == 0b00 ) {
@@ -764,7 +789,7 @@ void RFM69::readAllRegs()
} else { } else {
SerialPrint ( "0 -> signal strength is above RssiThreshold\n" ); SerialPrint ( "0 -> signal strength is above RssiThreshold\n" );
} }
SerialPrint ( "\nAction taken after acceptance of a packet in Listen mode:\nListenEnd : " ); SerialPrint ( "\nAction taken after acceptance of a packet in Listen mode:\nListenEnd : " );
val = (regVal >> 1 ) & 0x3; val = (regVal >> 1 ) & 0x3;
if ( val == 0b00 ) { if ( val == 0b00 ) {
@@ -776,12 +801,12 @@ void RFM69::readAllRegs()
} else if ( val == 0b11 ) { } else if ( val == 0b11 ) {
SerialPrint ( "11 -> Reserved\n" ); SerialPrint ( "11 -> Reserved\n" );
} }
SerialPrint ( "\n" ); SerialPrint ( "\n" );
break; break;
} }
default : { default : {
} }
} }
@@ -794,12 +819,12 @@ uint8_t RFM69::readTemperature(uint8_t calFactor) // returns centigrade
{ {
setMode(RF69_MODE_STANDBY); setMode(RF69_MODE_STANDBY);
writeReg(REG_TEMP1, RF_TEMP1_MEAS_START); writeReg(REG_TEMP1, RF_TEMP1_MEAS_START);
while ((readReg(REG_TEMP1) & RF_TEMP1_MEAS_RUNNING)); while ((readReg(REG_TEMP1) & RF_TEMP1_MEAS_RUNNING)) {}
return ~readReg(REG_TEMP2) + COURSE_TEMP_COEF + calFactor; // 'complement' corrects the slope, rising temp = rising val return ~readReg(REG_TEMP2) + COURSE_TEMP_COEF + calFactor; // 'complement' corrects the slope, rising temp = rising val
} // COURSE_TEMP_COEF puts reading in the ballpark, user can add additional correction } // COURSE_TEMP_COEF puts reading in the ballpark, user can add additional correction
void RFM69::rcCalibration() void RFM69::rcCalibration()
{ {
writeReg(REG_OSC1, RF_OSC1_RCCAL_START); writeReg(REG_OSC1, RF_OSC1_RCCAL_START);
while ((readReg(REG_OSC1) & RF_OSC1_RCCAL_DONE) == 0x00); while ((readReg(REG_OSC1) & RF_OSC1_RCCAL_DONE) == 0x00) {}
} }
+9 -3
View File
@@ -79,9 +79,15 @@ void SPIClass::setClockDivider(uint16_t divider) {
} }
void SPIClass::chipSelect(int csn_pin) { void SPIClass::chipSelect(int csn_pin) {
if (csn_pin == RPI_GPIO_P1_26) csn_pin = BCM2835_SPI_CS1; if (csn_pin == RPI_GPIO_P1_26) {
else if (csn_pin == RPI_GPIO_P1_24) csn_pin = BCM2835_SPI_CS0; csn_pin = BCM2835_SPI_CS1;
else csn_pin = BCM2835_SPI_CS0; }
else if (csn_pin == RPI_GPIO_P1_24) {
csn_pin = BCM2835_SPI_CS0;
}
else {
csn_pin = BCM2835_SPI_CS0;
}
bcm2835_spi_chipSelect(csn_pin); bcm2835_spi_chipSelect(csn_pin);
delayMicroseconds(5); delayMicroseconds(5);
} }
+41 -32
View File
@@ -7,28 +7,28 @@
// > Updated Jan. 5, 2015, TomWS1, modified writeBytes to allow blocks > 256 bytes and handle page misalignment. // > Updated Jan. 5, 2015, TomWS1, modified writeBytes to allow blocks > 256 bytes and handle page misalignment.
// > Updated Feb. 26, 2015 TomWS1, added support for SPI Transactions (Arduino 1.5.8 and above) // > Updated Feb. 26, 2015 TomWS1, added support for SPI Transactions (Arduino 1.5.8 and above)
// > Selective merge by Felix after testing in IDE 1.0.6, 1.6.4 // > Selective merge by Felix after testing in IDE 1.0.6, 1.6.4
// > Updated May 19, 2016 D-H-R, added support for SST25/Microchip Flash which does not support Page programming with OPCode 0x02, // > Updated May 19, 2016 D-H-R, added support for SST25/Microchip Flash which does not support Page programming with OPCode 0x02,
// > use define MY_SPIFLASH_SST25TYPE for SST25 Type Flash Memory // > use define MY_SPIFLASH_SST25TYPE for SST25 Type Flash Memory
// ********************************************************************************** // **********************************************************************************
// License // License
// ********************************************************************************** // **********************************************************************************
// This program is free software; you can redistribute it // This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU General // and/or modify it under the terms of the GNU General
// Public License as published by the Free Software // Public License as published by the Free Software
// Foundation; either version 3 of the License, or // Foundation; either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// This program is distributed in the hope that it will // This program is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY; without even the // be useful, but WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A // implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE. See the GNU General Public // PARTICULAR PURPOSE. See the GNU General Public
// License for more details. // License for more details.
// //
// You should have received a copy of the GNU General // You should have received a copy of the GNU General
// Public License along with this program. // Public License along with this program.
// If not, see <http://www.gnu.org/licenses/>. // If not, see <http://www.gnu.org/licenses/>.
// //
// Licence can be viewed at // Licence can be viewed at
// http://www.gnu.org/licenses/gpl-3.0.txt // http://www.gnu.org/licenses/gpl-3.0.txt
// //
// Please maintain this license information along with authorship // Please maintain this license information along with authorship
@@ -81,7 +81,7 @@ void SPIFlash::unselect() {
//restore SPI settings to what they were before talking to the FLASH chip //restore SPI settings to what they were before talking to the FLASH chip
#ifdef SPI_HAS_TRANSACTION #ifdef SPI_HAS_TRANSACTION
SPI.endTransaction(); SPI.endTransaction();
#else #else
interrupts(); interrupts();
#endif #endif
#ifndef ESP8266 #ifndef ESP8266
@@ -104,7 +104,7 @@ boolean SPIFlash::initialize()
unselect(); unselect();
wakeup(); wakeup();
if (_jedecID == 0 || readDeviceId() == _jedecID) { if (_jedecID == 0 || readDeviceId() == _jedecID) {
command(SPIFLASH_STATUSWRITE, true); // Write Status Register command(SPIFLASH_STATUSWRITE, true); // Write Status Register
SPI.transfer(0); // Global Unprotect SPI.transfer(0); // Global Unprotect
@@ -142,8 +142,9 @@ uint8_t* SPIFlash::readUniqueId()
SPI.transfer(0); SPI.transfer(0);
SPI.transfer(0); SPI.transfer(0);
SPI.transfer(0); SPI.transfer(0);
for (uint8_t i=0;i<8;i++) for (uint8_t i=0;i<8;i++) {
UNIQUEID[i] = SPI.transfer(0); UNIQUEID[i] = SPI.transfer(0);
}
unselect(); unselect();
return UNIQUEID; return UNIQUEID;
} }
@@ -166,8 +167,9 @@ void SPIFlash::readBytes(uint32_t addr, void* buf, uint16_t len) {
SPI.transfer(addr >> 8); SPI.transfer(addr >> 8);
SPI.transfer(addr); SPI.transfer(addr);
SPI.transfer(0); //"dont care" SPI.transfer(0); //"dont care"
for (uint16_t i = 0; i < len; ++i) for (uint16_t i = 0; i < len; ++i) {
((uint8_t*) buf)[i] = SPI.transfer(0); ((uint8_t*) buf)[i] = SPI.transfer(0);
}
unselect(); unselect();
} }
@@ -239,12 +241,12 @@ void SPIFlash::writeBytes(uint32_t addr, const void* buf, uint16_t len) {
uint16_t i=0; uint16_t i=0;
uint8_t oddAdr=0; uint8_t oddAdr=0;
char s[5]; char s[5];
command(SPIFLASH_AAIWORDPROGRAM, true); // Byte/Page Program command(SPIFLASH_AAIWORDPROGRAM, true); // Byte/Page Program
SPI.transfer(addr >> 16); SPI.transfer(addr >> 16);
SPI.transfer(addr >> 8); SPI.transfer(addr >> 8);
SPI.transfer(addr); SPI.transfer(addr);
if (addr%2){ if (addr%2){
//start address is not even, i.e. first byte of word must be 0xff //start address is not even, i.e. first byte of word must be 0xff
SPI.transfer(0xff); SPI.transfer(0xff);
@@ -252,25 +254,31 @@ void SPIFlash::writeBytes(uint32_t addr, const void* buf, uint16_t len) {
unselect(); unselect();
oddAdr=1; //following addresses must all be shifted one off oddAdr=1; //following addresses must all be shifted one off
len--; len--;
if (len > 0) command(SPIFLASH_AAIWORDPROGRAM); //If for loop will run issue Wordprogram command if (len > 0) {
command(SPIFLASH_AAIWORDPROGRAM); //If for loop will run issue Wordprogram command
}
} }
for (i=0;i<(len/2);i++){ for (i=0;i<(len/2);i++){
//AAI command must be set before every new word //AAI command must be set before every new word
if (i>0) command(SPIFLASH_AAIWORDPROGRAM); //Wordprogram command for first write has been issued before if (i>0) {
command(SPIFLASH_AAIWORDPROGRAM); //Wordprogram command for first write has been issued before
}
SPI.transfer(((uint8_t*) buf)[i*2+oddAdr]); SPI.transfer(((uint8_t*) buf)[i*2+oddAdr]);
SPI.transfer(((uint8_t*) buf)[i*2+1+oddAdr]); SPI.transfer(((uint8_t*) buf)[i*2+1+oddAdr]);
unselect(); unselect();
} }
if (len-i*2 == 1){ if (len-i*2 == 1){
//There is one byte (i.e. half word) left. This happens if len was odd or (len was even and addr odd) //There is one byte (i.e. half word) left. This happens if len was odd or (len was even and addr odd)
if (i>0) command(SPIFLASH_AAIWORDPROGRAM); //if for loop had not run wordprogram command from before is still valid if (i>0) {
command(SPIFLASH_AAIWORDPROGRAM); //if for loop had not run wordprogram command from before is still valid
}
SPI.transfer(((uint8_t*) buf)[i*2+oddAdr]); SPI.transfer(((uint8_t*) buf)[i*2+oddAdr]);
SPI.transfer(0xff); SPI.transfer(0xff);
unselect(); unselect();
} }
command(SPIFLASH_WRITEDISABLE); //end AAI programming command(SPIFLASH_WRITEDISABLE); //end AAI programming
unselect(); unselect();
#else #else
@@ -284,11 +292,12 @@ void SPIFlash::writeBytes(uint32_t addr, const void* buf, uint16_t len) {
SPI.transfer(addr >> 16); SPI.transfer(addr >> 16);
SPI.transfer(addr >> 8); SPI.transfer(addr >> 8);
SPI.transfer(addr); SPI.transfer(addr);
for (uint16_t i = 0; i < n; i++) for (uint16_t i = 0; i < n; i++) {
SPI.transfer(((uint8_t*) buf)[offset + i]); SPI.transfer(((uint8_t*) buf)[offset + i]);
}
unselect(); unselect();
addr+=n; // adjust the addresses and remaining bytes by what we've just transferred. addr+=n; // adjust the addresses and remaining bytes by what we've just transferred.
offset +=n; offset +=n;
len -= n; len -= n;