Compare commits

..

1 Commits

Author SHA1 Message Date
Anthony Hinsinger 87f9232d49 Started nvstore tests 7 years ago
  1. 14
      .gitignore
  2. 24
      README.md
  3. 188
      main.cpp
  4. 50
      mbed_app.json
  5. 47
      scripts/gen_images.sh

14
.gitignore vendored

@ -1,16 +1,4 @@
*.pyc *.pyc
BUILD BUILD
mbed_config.h mbed_config.h
mbed_app.json
mbed-os
Cayenne-LPP
mbed-lora-radio-drv
sensors/DHT
sensors/HX711
*.bin
devices.txt
# mbed vscode export generated files
GettingStarted.html
.vscode

24
README.md

@ -13,30 +13,12 @@ mbed toolchain GCC_ARM
mbed target NUCLEO_L073RZ mbed target NUCLEO_L073RZ
# set-up the compiler path if needed # set-up the compiler path if needed
mbed config -G GCC_ARM_PATH /opt/gcc-arm-none-eabi-7-2017-q4-major/bin mbed config -G GCC_ARM_PATH /opt/gcc-arm-none-eabi-7-2017-q4-major/bin
``` cp mbed_app.json.sample mbed_app.json
# modify lora.device-eui, lora.application-eui and lora.application-key in mbed_app.json
### Bootstrap mode
This mode is used to initialize a mbed NVStore on the flash and store board-specific parameters.
To compile the bootstrap binary you have to set "mode-bootstrap" to true into mbed_app.json and set
lorawan EUIs and key.
```
mbed compile --profile profiles/release.json
```
Then you can use flash the board and start it. You can check the serial console to see reporting.
### Production mode
Just reset "mode-boostrap" to false and compile it (you can delete BUILD folder from previous compilation) :
```
mbed compile --profile profiles/release.json mbed compile --profile profiles/release.json
``` ```
In this mode, lorawan parameters are ignored (because the program get it from the flash) but Then you can use stm32flash or - may be better - a stlink interface to copy the generated .bin file onto the RAK811.
leave it as-is because they are used to determine the stored size ot the euis and key.
## Notes ## Notes

188
main.cpp

@ -6,61 +6,6 @@
#include "mbed.h" #include "mbed.h"
#include "nvstore.h" #include "nvstore.h"
#define NVKEY_LORA_DEVICE_EUI 0x01
#define NVKEY_LORA_APP_EUI 0x02
#define NVKEY_LORA_APP_KEY 0x03
#define NVKEY_HX711_OFFSET 0x04
#define NVKEY_HX711_SCALE 0x05
#if MBED_CONF_APP_MODE_BOOTSTRAP
const static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI;
const static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI;
const static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY;
int main(void) {
int rc;
uint16_t key;
NVStore &nvstore = NVStore::get_instance();
rc = nvstore.init();
if (rc != NVSTORE_SUCCESS) {
printf("Unable to init NVStore : %d\n", rc);
return -1;
}
rc = nvstore.reset();
if (rc != NVSTORE_SUCCESS) {
printf("Unable to reset NVStore : %d\n", rc);
return -1;
}
printf("NVStore initiated and reseted\n");
key = NVKEY_LORA_DEVICE_EUI;
if (nvstore.set(key, sizeof(dev_eui), dev_eui) != NVSTORE_SUCCESS) {
printf("Unable to write LoRa Device EUI\n");
}
key = NVKEY_LORA_APP_EUI;
if (nvstore.set(key, sizeof(app_eui), app_eui) != NVSTORE_SUCCESS) {
printf("Unable to write LoRa Application EUI\n");
}
key = NVKEY_LORA_APP_KEY;
if (nvstore.set(key, sizeof(app_key), app_key) != NVSTORE_SUCCESS) {
printf("Unable to write LoRa Application key\n");
}
while(1) {
printf("Bootstrap done\n");
wait(1);
}
}
#else // MBED_CONF_APP_MODE_BOOTSTRAP
static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI;
static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI;
static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY;
#if MBED_CONF_APP_DHT_ENABLED #if MBED_CONF_APP_DHT_ENABLED
#include "DHT.h" #include "DHT.h"
#endif #endif
@ -93,28 +38,22 @@ static CayenneLPP cayenne(51);
#if MBED_CONF_APP_BATTERY_ENABLED #if MBED_CONF_APP_BATTERY_ENABLED
AnalogIn bat(MBED_CONF_APP_BATTERY_ADC); AnalogIn bat(MBED_CONF_APP_BATTERY_ADC);
AnalogIn vref(ADC_VREF); AnalogIn vrefint(ADC_VREF);
static float battery_voltage() { static float battery_voltage() {
float vbat = bat.read(); float vbat = bat.read();
float vrefin = vref.read(); double vdd = (1.224f) / vrefint.read();
float vrefcal = (float)(*(uint16_t*)VREFINT_CAL_ADDR) * (1.0f / (float)0xFFF);
float vdda = 3.0f * vrefcal / vrefin;
return vbat * vdda * MBED_CONF_APP_BATTERY_RATIO; return vbat * MBED_CONF_APP_BATTERY_RATIO * vdd;
} }
static uint8_t battery_level() { static uint8_t battery_level() {
float vbat = battery_voltage(); float vbat = battery_voltage();
if (vbat >= MBED_CONF_APP_BATTERY_MAX) { double ratio = 253.0f / (4.2f - 3.3f);
return 254; int value = ratio * (vbat - 3.4f) + 1.0f;
} else if (vbat > MBED_CONF_APP_BATTERY_MIN && vbat < MBED_CONF_APP_BATTERY_MAX) {
return ( 253 * ( vbat - MBED_CONF_APP_BATTERY_MIN ) ) / ( MBED_CONF_APP_BATTERY_MAX - MBED_CONF_APP_BATTERY_MIN ) + 1; return value < 1 ? 1 : (value > 254 ? 254 : value);
} else {
return 1;
}
} }
#endif #endif
@ -128,45 +67,35 @@ HX711 loadcell(MBED_CONF_APP_HX711_DATA, MBED_CONF_APP_HX711_CLK);
int main(void) { int main(void) {
lorawan_status_t retcode; lorawan_status_t retcode;
lorawan_connect_t connect;
int rc;
uint16_t key;
uint16_t readsize;
// NVStore is a sigleton, get its instance #if NVSTORE_ENABLED
NVStore &nvstore = NVStore::get_instance(); NVStore &nvstore = NVStore::get_instance();
int rc;
if (nvstore.init() != NVSTORE_SUCCESS) { uint16_t key;
debug("\r\n NVStore initialization failed! \r\n"); // Values read or written by NVStore need to be aligned to a uint32_t address (even if their sizes
return -1; // aren't)
} uint32_t value;
// Initialize NVstore. Note that it can be skipped, as it is lazily called by all other APIs
key = NVKEY_LORA_DEVICE_EUI; rc = nvstore.init();
rc = nvstore.get(key, sizeof(dev_eui), dev_eui, readsize); printf("Init NVStore. \n");
if (rc != NVSTORE_SUCCESS || readsize != sizeof(dev_eui)) { // Show NVStore size, maximum number of keys and area addresses and sizes
debug("\r\n Failed to read LoRa Device EUI from NVStore! \r\n"); printf("NVStore size is %d.\n", nvstore.size());
return -1; printf("NVStore max number of keys is %d (out of %d possible ones in this flash configuration).\n",
} nvstore.get_max_keys(), nvstore.get_max_possible_keys());
printf("NVStore areas:\n");
key = NVKEY_LORA_APP_EUI; for (uint8_t area = 0; area < NVSTORE_NUM_AREAS; area++) {
rc = nvstore.get(key, sizeof(app_eui), app_eui, readsize); uint32_t area_address;
if (rc != NVSTORE_SUCCESS || readsize != sizeof(app_eui)) { size_t area_size;
debug("\r\n Failed to read LoRa Application EUI from NVStore! \r\n"); nvstore.get_area_params(area, area_address, area_size);
return -1; printf("Area %d: address 0x%08lx, size %d (0x%x).\n", area, area_address, area_size, area_size);
}
key = NVKEY_LORA_APP_KEY;
rc =nvstore.get(key, sizeof(app_key), app_key, readsize);
if (rc != NVSTORE_SUCCESS || readsize != sizeof(app_key)) {
debug("\r\n Failed to read LoRa Application Key from NVStore! \r\n");
return -1;
} }
#else
printf("NVStore is disabled for this board\n");
#endif
connect.connect_type = LORAWAN_CONNECTION_OTAA; while(1) {
connect.connection_u.otaa.app_eui = const_cast<uint8_t *>(app_eui); wait(1);
connect.connection_u.otaa.dev_eui = const_cast<uint8_t *>(dev_eui); }
connect.connection_u.otaa.app_key = const_cast<uint8_t *>(app_key);
connect.connection_u.otaa.nb_trials = MBED_CONF_LORA_NB_TRIALS;
#if MBED_CONF_APP_HX711_ENABLED #if MBED_CONF_APP_HX711_ENABLED
loadcell.powerDown(); loadcell.powerDown();
@ -204,7 +133,7 @@ int main(void) {
debug("\r\n Adaptive data rate (ADR) - Enabled \r\n"); debug("\r\n Adaptive data rate (ADR) - Enabled \r\n");
retcode = lorawan.connect(connect); retcode = lorawan.connect();
if(retcode == LORAWAN_STATUS_OK || retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) { if(retcode == LORAWAN_STATUS_OK || retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) {
} else { } else {
@ -225,30 +154,16 @@ int main(void) {
*/ */
static void send_message() { static void send_message() {
int16_t retcode; int16_t retcode;
int eid;
#if MBED_CONF_APP_BATTERY_ENABLED && MBED_CONF_APP_BATTERY_IN_LPP
// setup next transmission cayenne.addAnalogInput(1, battery_voltage());
eid = ev_queue.call_in(MBED_CONF_APP_TX_TIMER, send_message); #endif
// check backoff time before sending new frame
if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
lorawan_status_t status;
int backoff;
status = lorawan.get_backoff_metadata(backoff);
if (status == LORAWAN_STATUS_OK && backoff > 0) {
debug("\r\n %d ms backoff, delay next send \r\n", backoff);
ev_queue.cancel(eid);
ev_queue.call_in(backoff+MBED_CONF_APP_TX_TIMER, send_message);
return;
}
}
#if MBED_CONF_APP_DHT_ENABLED #if MBED_CONF_APP_DHT_ENABLED
int err = dht.read(); int err = dht.read();
if(err == DHT::SUCCESS) { if(err == DHT::SUCCESS) {
cayenne.addTemperature(MBED_CONF_APP_DHT_TEMP_LPP_ID, dht.getTemperature()); cayenne.addTemperature(1, dht.getTemperature());
cayenne.addRelativeHumidity(MBED_CONF_APP_DHT_HUM_LPP_ID, dht.getHumidity()); cayenne.addRelativeHumidity(1, dht.getHumidity());
} else { } else {
debug("Error code : %d\r\n", err); debug("Error code : %d\r\n", err);
} }
@ -257,15 +172,11 @@ static void send_message() {
#if MBED_CONF_APP_HX711_ENABLED #if MBED_CONF_APP_HX711_ENABLED
loadcell.powerUp(); loadcell.powerUp();
if(loadcell.waitReadyRetry(20, 100)) { if(loadcell.waitReadyRetry(20, 100)) {
cayenne.addAnalogInput(MBED_CONF_APP_HX711_LPP_ID, loadcell.getUnits(5)); cayenne.addAnalogInput(2, loadcell.getUnits(5));
} }
loadcell.powerDown(); loadcell.powerDown();
#endif #endif
#if MBED_CONF_APP_BATTERY_ENABLED && MBED_CONF_APP_BATTERY_IN_LPP
cayenne.addAnalogInput(MBED_CONF_APP_BATTERY_LPP_ID, battery_voltage());
#endif
// No data to send // No data to send
if(cayenne.getSize() == 0) { if(cayenne.getSize() == 0) {
return; return;
@ -312,7 +223,13 @@ static void lora_event_handler(lorawan_event_t event) {
switch(event) { switch(event) {
case CONNECTED: case CONNECTED:
debug("\r\n Connection - Successful \r\n"); debug("\r\n Connection - Successful \r\n");
send_message(); if(MBED_CONF_LORA_DUTY_CYCLE_ON) {
send_message();
} else {
send_message();
ev_queue.call_every(MBED_CONF_APP_TX_TIMER, send_message);
}
break; break;
case DISCONNECTED: case DISCONNECTED:
ev_queue.break_dispatch(); ev_queue.break_dispatch();
@ -320,12 +237,19 @@ static void lora_event_handler(lorawan_event_t event) {
break; break;
case TX_DONE: case TX_DONE:
debug("\r\n Message Sent to Network Server \r\n"); debug("\r\n Message Sent to Network Server \r\n");
if(MBED_CONF_LORA_DUTY_CYCLE_ON) {
send_message();
}
break; break;
case TX_TIMEOUT: case TX_TIMEOUT:
case TX_ERROR: case TX_ERROR:
case TX_CRYPTO_ERROR: case TX_CRYPTO_ERROR:
case TX_SCHEDULING_ERROR: case TX_SCHEDULING_ERROR:
debug("\r\n Transmission Error - EventCode = %d \r\n", event); debug("\r\n Transmission Error - EventCode = %d \r\n", event);
// try again
if(MBED_CONF_LORA_DUTY_CYCLE_ON) {
send_message();
}
break; break;
case RX_DONE: case RX_DONE:
debug("\r\n Received message from Network Server \r\n"); debug("\r\n Received message from Network Server \r\n");
@ -341,6 +265,4 @@ static void lora_event_handler(lorawan_event_t event) {
default: default:
MBED_ASSERT("Unknown Event"); MBED_ASSERT("Unknown Event");
} }
} }
#endif // MBED_APP_MODE_BOOTSTRAP

50
mbed_app.json

@ -1,7 +1,6 @@
{ {
"config": { "config": {
"mode-bootstrap": { "value": false }, "tx-timer": { "value": 30000 },
"tx-timer": { "value": 600000 },
"lora-radio": { "lora-radio": {
"help": "Which radio to use (options: SX1272,SX1276)", "help": "Which radio to use (options: SX1272,SX1276)",
"value": "SX1276" "value": "SX1276"
@ -25,45 +24,39 @@
"lora-ant-switch": { "value": "NC" }, "lora-ant-switch": { "value": "NC" },
"lora-pwr-amp-ctl": { "value": "NC" }, "lora-pwr-amp-ctl": { "value": "NC" },
"lora-tcxo": { "value": "NC" }, "lora-tcxo": { "value": "NC" },
"battery-enabled": { "value": false }, "battery-enabled": { "value": "false" },
"battery-lpp-id": { "value": 1 }, "battery-in-lpp": { "value": "false" },
"battery-in-lpp": { "value": false },
"battery-adc": { "value": "NC" }, "battery-adc": { "value": "NC" },
"battery-min": { "value": "3.20f" },
"battery-max": { "value": "4.15f" },
"battery-ratio": { "value": "2.0f" }, "battery-ratio": { "value": "2.0f" },
"hx711-enabled": { "value": false }, "dht-enabled": { "value": "false" },
"hx711-lpp-id": { "value": 2 }, "dht-type": { "value": "DHT::DHT22" },
"dht-data": { "value": "NC" },
"hx711-enabled": { "value": "false" },
"hx711-clk": { "value": "NC" }, "hx711-clk": { "value": "NC" },
"hx711-data": { "value": "NC" }, "hx711-data": { "value": "NC" },
"hx711-scale": { "value": "1.0f" }, "hx711-scale": { "value": "1.0f" },
"hx711-offset": { "value": 0 }, "hx711-offset": { "value": 0 }
"dht-enabled": { "value": false },
"dht-temp-lpp-id": { "value": 3 },
"dht-hum-lpp-id": { "value": 4 },
"dht-type": { "value": "DHT::DHT22" },
"dht-data": { "value": "NC" }
}, },
"target_overrides": { "target_overrides": {
"*": { "*": {
"mode-bootstrap": false,
"tx-timer": 600000,
"platform.stdio-convert-newlines": true, "platform.stdio-convert-newlines": true,
"platform.stdio-baud-rate": 115200, "platform.stdio-baud-rate": 115200,
"platform.default-serial-baud-rate": 115200, "platform.default-serial-baud-rate": 115200,
"lora.app-port": 3, "lora.app-port": 3,
"lora.duty-cycle-on": true, "lora.over-the-air-activation": true,
"lora.duty-cycle-on": false,
"lora.phy": 0, "lora.phy": 0,
"lora.device-eui": "{ 0xAB, 0xBA, 0xAB, 0xBA, 0xAB, 0xBA, 0xAB, 0xBA }", "lora.device-eui": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }",
"lora.application-eui": "{ 0xAC, 0xCA, 0xAC, 0xCA, 0xAC, 0xCA, 0xAC, 0xCA }", "lora.application-eui": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }",
"lora.application-key": "{ 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA }" "lora.application-key": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }"
}, },
"NUCLEO_L073RZ": { "NUCLEO_L073RZ": {
"main_stack_size": 1024, "main_stack_size": 1024,
"target.lpticker_lptim": 0, "target.lpticker_lptim": 0,
"target.clock_source": "USE_PLL_HSI", "target.clock_source": "USE_PLL_HSI",
"sx1272-lora-driver.radio-variant": "SX1272MB2XAS", "lora.duty-cycle-on": false,
"tx-timer": 600000,
"lora-radio": "SX1272", "lora-radio": "SX1272",
"lora-spi-mosi": "D11", "lora-spi-mosi": "D11",
"lora-spi-miso": "D12", "lora-spi-miso": "D12",
@ -80,21 +73,26 @@
"lora-rf-switch-ctl2": "NC", "lora-rf-switch-ctl2": "NC",
"lora-txctl": "NC", "lora-txctl": "NC",
"lora-rxctl": "NC", "lora-rxctl": "NC",
"lora-ant-switch": "NC", "lora-ant-switch": "A4",
"lora-pwr-amp-ctl": "NC", "lora-pwr-amp-ctl": "NC",
"lora-tcxo": "NC", "lora-tcxo": "NC",
"battery-enabled": true, "battery-enabled": true,
"battery-in-lpp": true, "battery-in-lpp": true,
"battery-adc": "A1", "battery-adc": "A1",
"battery-ratio": "2.0f", "battery-ratio": "2.0f",
"dht-enabled": true,
"dht-data": "D8",
"dht-type": "DHT::DHT22",
"hx711-enabled": true, "hx711-enabled": true,
"hx711-clk": "D6", "hx711-clk": "D6",
"hx711-data": "D7", "hx711-data": "D7",
"hx711-scale": "21000.0f", "hx711-scale": "21000.0f",
"hx711-offset": 59600, "hx711-offset": 59600,
"dht-enabled": true, "nvstore.max_keys": 20,
"dht-data": "D8", "nvstore.area_1_address": "0x0802e000",
"dht-type": "DHT::DHT22" "nvstore.area_1_size" : "0x1000",
"nvstore.area_2_address": "0x0802f000",
"nvstore.area_2_size" : "0x1000"
}, },
"MTB_RAK811": { "MTB_RAK811": {

47
scripts/gen_images.sh

@ -1,47 +0,0 @@
#!/bin/bash
# patterns
DEVICEEUI=ABBAABBAABBAABBA
APPEUI=ACCAACCAACCAACCA
APPKEY=ADDAADDAADDAADDAADDAADDAADDAADDA
if [ $# -ne 2 ]; then
echo "gen_images <master_binary> <devices_file>\n"
echo "devices file must be in the form :\n"
echo "dev1name:dev1eui:dev1appeui:dev1appkey"
echo "dev2name:dev2eui:dev2appeui:dev2appkey\n"
exit 1;
fi
SED=sed
MASTER=$1
DEVICES=$2
if [[ $OSTYPE == "darwin"* ]]; then
if ! command -v gsed > /dev/null 2>&1; then
echo "You need gnu-sed on darwin system (available with homebrew)"
exit 1
fi
SED=gsed
fi
if [ ! -e $MASTER ]; then
echo "The master file $MASTER doesn't exists"
exit 1;
fi
if [ ! -e $DEVICES ]; then
echo "The devices file $DEVICES doesn't exists"
exit 1;
fi
for DEVICE in $(cat $DEVICES); do
name=$(echo $DEVICE | cut -d : -f 1)
deviceeui=$(echo $DEVICE | cut -d : -f 2)
appeui=$(echo $DEVICE | cut -d : -f 3)
appkey=$(echo $DEVICE | cut -d : -f 4)
echo "Generating device $name ($deviceeui)"
hexdump -ve '1/1 "%.2X"' $MASTER | $SED "s/${DEVICEEUI}/${deviceeui}/; s/${APPEUI}/${appeui}/; s/${APPKEY}/${appkey}/" | xxd -r -p - ${deviceeui}.bin
done
exit;
Loading…
Cancel
Save