Compare commits
19 Commits
e93dc481e0
...
2019.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 32df3b9a2d | |||
| 764d42095c | |||
| cb1de9bc8c | |||
| 715d0ee1a8 | |||
| 3f92cc41a1 | |||
| 66a23299f3 | |||
| cf1c0d1737 | |||
| dcf7bcbf71 | |||
| e73b620ef4 | |||
| 1a6e219f3a | |||
| fca0241c2d | |||
| 8b930cc554 | |||
| 36dfb179dd | |||
| c9c6a3d003 | |||
| 70756dd33d | |||
| 596d6869c8 | |||
| 80dedb1490 | |||
| 2e3ad42102 | |||
| e71159cd35 |
+13
-1
@@ -1,4 +1,16 @@
|
|||||||
*.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
|
||||||
@@ -13,12 +13,30 @@ 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
|
|
||||||
mbed compile --profile minimal-printf/profiles/release.json
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then you can use stm32flash or - may be better - a stlink interface to copy the generated .bin file onto the RAK811.
|
### 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
|
||||||
|
```
|
||||||
|
|
||||||
|
In this mode, lorawan parameters are ignored (because the program get it from the flash) but
|
||||||
|
leave it as-is because they are used to determine the stored size ot the euis and key.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,62 @@
|
|||||||
#include "lorawan/LoRaWANInterface.h"
|
#include "lorawan/LoRaWANInterface.h"
|
||||||
#include "lorawan/system/lorawan_data_structures.h"
|
#include "lorawan/system/lorawan_data_structures.h"
|
||||||
#include "mbed.h"
|
#include "mbed.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"
|
||||||
@@ -37,6 +93,29 @@ 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);
|
||||||
|
|
||||||
|
static float battery_voltage() {
|
||||||
|
float vbat = bat.read();
|
||||||
|
float vrefin = vref.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t battery_level() {
|
||||||
|
float vbat = battery_voltage();
|
||||||
|
|
||||||
|
if (vbat >= MBED_CONF_APP_BATTERY_MAX) {
|
||||||
|
return 254;
|
||||||
|
} 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;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MBED_CONF_APP_DHT_ENABLED
|
#if MBED_CONF_APP_DHT_ENABLED
|
||||||
@@ -44,14 +123,50 @@ DHT dht(MBED_CONF_APP_DHT_DATA, MBED_CONF_APP_DHT_TYPE);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MBED_CONF_APP_HX711_ENABLED
|
#if MBED_CONF_APP_HX711_ENABLED
|
||||||
HX711 loadcell(MBED_CONF_APP_HX711_CLK, MBED_CONF_APP_HX711_DATA);
|
HX711 loadcell(MBED_CONF_APP_HX711_DATA, MBED_CONF_APP_HX711_CLK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//DigitalOut led(LED1, 1);
|
|
||||||
|
|
||||||
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
|
||||||
|
NVStore &nvstore = NVStore::get_instance();
|
||||||
|
|
||||||
|
if (nvstore.init() != NVSTORE_SUCCESS) {
|
||||||
|
debug("\r\n NVStore initialization failed! \r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = NVKEY_LORA_DEVICE_EUI;
|
||||||
|
rc = nvstore.get(key, sizeof(dev_eui), dev_eui, readsize);
|
||||||
|
if (rc != NVSTORE_SUCCESS || readsize != sizeof(dev_eui)) {
|
||||||
|
debug("\r\n Failed to read LoRa Device EUI from NVStore! \r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
key = NVKEY_LORA_APP_EUI;
|
||||||
|
rc = nvstore.get(key, sizeof(app_eui), app_eui, readsize);
|
||||||
|
if (rc != NVSTORE_SUCCESS || readsize != sizeof(app_eui)) {
|
||||||
|
debug("\r\n Failed to read LoRa Application EUI from NVStore! \r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect.connect_type = LORAWAN_CONNECTION_OTAA;
|
||||||
|
connect.connection_u.otaa.app_eui = const_cast<uint8_t *>(app_eui);
|
||||||
|
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();
|
||||||
@@ -68,6 +183,9 @@ int main(void) {
|
|||||||
debug("\r\n Mbed LoRaWANStack initialized \r\n");
|
debug("\r\n Mbed LoRaWANStack initialized \r\n");
|
||||||
|
|
||||||
callbacks.events = mbed::callback(lora_event_handler);
|
callbacks.events = mbed::callback(lora_event_handler);
|
||||||
|
#if MBED_CONF_APP_BATTERY_ENABLED
|
||||||
|
callbacks.battery_level = mbed::callback(battery_level);
|
||||||
|
#endif
|
||||||
lorawan.add_app_callbacks(&callbacks);
|
lorawan.add_app_callbacks(&callbacks);
|
||||||
|
|
||||||
// Set number of retries in case of CONFIRMED messages
|
// Set number of retries in case of CONFIRMED messages
|
||||||
@@ -86,9 +204,7 @@ int main(void) {
|
|||||||
|
|
||||||
debug("\r\n Adaptive data rate (ADR) - Enabled \r\n");
|
debug("\r\n Adaptive data rate (ADR) - Enabled \r\n");
|
||||||
|
|
||||||
//led = 0;
|
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 {
|
||||||
@@ -109,18 +225,30 @@ 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
|
// setup next transmission
|
||||||
float vbat = bat.read();
|
eid = ev_queue.call_in(MBED_CONF_APP_TX_TIMER, send_message);
|
||||||
vbat = vbat * MBED_CONF_APP_BATTERY_RATIO * 3.3f;
|
|
||||||
cayenne.addAnalogInput(1, vbat);
|
// check backoff time before sending new frame
|
||||||
#endif
|
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(1, dht.getTemperature());
|
cayenne.addTemperature(MBED_CONF_APP_DHT_TEMP_LPP_ID, dht.getTemperature());
|
||||||
cayenne.addRelativeHumidity(1, dht.getHumidity());
|
cayenne.addRelativeHumidity(MBED_CONF_APP_DHT_HUM_LPP_ID, dht.getHumidity());
|
||||||
} else {
|
} else {
|
||||||
debug("Error code : %d\r\n", err);
|
debug("Error code : %d\r\n", err);
|
||||||
}
|
}
|
||||||
@@ -129,11 +257,15 @@ 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(2, loadcell.getUnits(5));
|
cayenne.addAnalogInput(MBED_CONF_APP_HX711_LPP_ID, 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;
|
||||||
@@ -179,15 +311,8 @@ static void receive_message() {
|
|||||||
static void lora_event_handler(lorawan_event_t event) {
|
static void lora_event_handler(lorawan_event_t event) {
|
||||||
switch(event) {
|
switch(event) {
|
||||||
case CONNECTED:
|
case CONNECTED:
|
||||||
//led = 1;
|
|
||||||
debug("\r\n Connection - Successful \r\n");
|
debug("\r\n Connection - Successful \r\n");
|
||||||
if(MBED_CONF_LORA_DUTY_CYCLE_ON) {
|
|
||||||
send_message();
|
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();
|
||||||
@@ -195,19 +320,12 @@ 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");
|
||||||
@@ -224,3 +342,5 @@ static void lora_event_handler(lorawan_event_t event) {
|
|||||||
MBED_ASSERT("Unknown Event");
|
MBED_ASSERT("Unknown Event");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // MBED_APP_MODE_BOOTSTRAP
|
||||||
+128
@@ -0,0 +1,128 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"mode-bootstrap": { "value": false },
|
||||||
|
"tx-timer": { "value": 600000 },
|
||||||
|
"lora-radio": {
|
||||||
|
"help": "Which radio to use (options: SX1272,SX1276)",
|
||||||
|
"value": "SX1276"
|
||||||
|
},
|
||||||
|
"main_stack_size": { "value": 4096 },
|
||||||
|
"lora-spi-mosi": { "value": "NC" },
|
||||||
|
"lora-spi-miso": { "value": "NC" },
|
||||||
|
"lora-spi-sclk": { "value": "NC" },
|
||||||
|
"lora-cs": { "value": "NC" },
|
||||||
|
"lora-reset": { "value": "NC" },
|
||||||
|
"lora-dio0": { "value": "NC" },
|
||||||
|
"lora-dio1": { "value": "NC" },
|
||||||
|
"lora-dio2": { "value": "NC" },
|
||||||
|
"lora-dio3": { "value": "NC" },
|
||||||
|
"lora-dio4": { "value": "NC" },
|
||||||
|
"lora-dio5": { "value": "NC" },
|
||||||
|
"lora-rf-switch-ctl1": { "value": "NC" },
|
||||||
|
"lora-rf-switch-ctl2": { "value": "NC" },
|
||||||
|
"lora-txctl": { "value": "NC" },
|
||||||
|
"lora-rxctl": { "value": "NC" },
|
||||||
|
"lora-ant-switch": { "value": "NC" },
|
||||||
|
"lora-pwr-amp-ctl": { "value": "NC" },
|
||||||
|
"lora-tcxo": { "value": "NC" },
|
||||||
|
"battery-enabled": { "value": false },
|
||||||
|
"battery-lpp-id": { "value": 1 },
|
||||||
|
"battery-in-lpp": { "value": false },
|
||||||
|
"battery-adc": { "value": "NC" },
|
||||||
|
"battery-min": { "value": "3.20f" },
|
||||||
|
"battery-max": { "value": "4.15f" },
|
||||||
|
"battery-ratio": { "value": "2.0f" },
|
||||||
|
"hx711-enabled": { "value": false },
|
||||||
|
"hx711-lpp-id": { "value": 2 },
|
||||||
|
"hx711-clk": { "value": "NC" },
|
||||||
|
"hx711-data": { "value": "NC" },
|
||||||
|
"hx711-scale": { "value": "1.0f" },
|
||||||
|
"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": {
|
||||||
|
"*": {
|
||||||
|
"mode-bootstrap": false,
|
||||||
|
"tx-timer": 600000,
|
||||||
|
"platform.stdio-convert-newlines": true,
|
||||||
|
"platform.stdio-baud-rate": 115200,
|
||||||
|
"platform.default-serial-baud-rate": 115200,
|
||||||
|
"lora.app-port": 3,
|
||||||
|
"lora.duty-cycle-on": true,
|
||||||
|
"lora.phy": 0,
|
||||||
|
"lora.device-eui": "{ 0xAB, 0xBA, 0xAB, 0xBA, 0xAB, 0xBA, 0xAB, 0xBA }",
|
||||||
|
"lora.application-eui": "{ 0xAC, 0xCA, 0xAC, 0xCA, 0xAC, 0xCA, 0xAC, 0xCA }",
|
||||||
|
"lora.application-key": "{ 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA, 0xAD, 0xDA }"
|
||||||
|
},
|
||||||
|
|
||||||
|
"NUCLEO_L073RZ": {
|
||||||
|
"main_stack_size": 1024,
|
||||||
|
"target.lpticker_lptim": 0,
|
||||||
|
"target.clock_source": "USE_PLL_HSI",
|
||||||
|
"sx1272-lora-driver.radio-variant": "SX1272MB2XAS",
|
||||||
|
"lora-radio": "SX1272",
|
||||||
|
"lora-spi-mosi": "D11",
|
||||||
|
"lora-spi-miso": "D12",
|
||||||
|
"lora-spi-sclk": "D13",
|
||||||
|
"lora-cs": "D10",
|
||||||
|
"lora-reset": "A0",
|
||||||
|
"lora-dio0": "D2",
|
||||||
|
"lora-dio1": "D3",
|
||||||
|
"lora-dio2": "D4",
|
||||||
|
"lora-dio3": "D5",
|
||||||
|
"lora-dio4": "NC",
|
||||||
|
"lora-dio5": "NC",
|
||||||
|
"lora-rf-switch-ctl1": "NC",
|
||||||
|
"lora-rf-switch-ctl2": "NC",
|
||||||
|
"lora-txctl": "NC",
|
||||||
|
"lora-rxctl": "NC",
|
||||||
|
"lora-ant-switch": "NC",
|
||||||
|
"lora-pwr-amp-ctl": "NC",
|
||||||
|
"lora-tcxo": "NC",
|
||||||
|
"battery-enabled": true,
|
||||||
|
"battery-in-lpp": true,
|
||||||
|
"battery-adc": "A1",
|
||||||
|
"battery-ratio": "2.0f",
|
||||||
|
"hx711-enabled": true,
|
||||||
|
"hx711-clk": "D6",
|
||||||
|
"hx711-data": "D7",
|
||||||
|
"hx711-scale": "21000.0f",
|
||||||
|
"hx711-offset": 59600,
|
||||||
|
"dht-enabled": true,
|
||||||
|
"dht-data": "D8",
|
||||||
|
"dht-type": "DHT::DHT22"
|
||||||
|
},
|
||||||
|
|
||||||
|
"MTB_RAK811": {
|
||||||
|
"lora-radio": "SX1276",
|
||||||
|
"lora-spi-mosi": "SPI_RF_MOSI",
|
||||||
|
"lora-spi-miso": "SPI_RF_MISO",
|
||||||
|
"lora-spi-sclk": "SPI_RF_SCK",
|
||||||
|
"lora-cs": "SPI_RF_CS",
|
||||||
|
"lora-reset": "SPI_RF_RESET",
|
||||||
|
"lora-dio0": "DIO0",
|
||||||
|
"lora-dio1": "DIO1",
|
||||||
|
"lora-dio2": "DIO2",
|
||||||
|
"lora-dio3": "DIO3",
|
||||||
|
"lora-dio4": "DIO4",
|
||||||
|
"lora-dio5": "NC",
|
||||||
|
"lora-rf-switch-ctl1": "NC",
|
||||||
|
"lora-rf-switch-ctl2": "NC",
|
||||||
|
"lora-txctl": "ANT_CTX_PA",
|
||||||
|
"lora-rxctl": "ANT_CRX_RX",
|
||||||
|
"lora-ant-switch": "NC",
|
||||||
|
"lora-pwr-amp-ctl": "NC",
|
||||||
|
"lora-tcxo": "RF_TCXO_EN",
|
||||||
|
"battery-enabled": true,
|
||||||
|
"battery-adc": "PA_2",
|
||||||
|
"dht-enabled": true,
|
||||||
|
"dht-data": "PA_1",
|
||||||
|
"dht-type": "DHT::DHT22"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_lora_config.h\""]
|
||||||
|
}
|
||||||
@@ -1,296 +0,0 @@
|
|||||||
{
|
|
||||||
"config": {
|
|
||||||
"tx-timer": { "value": 30000 },
|
|
||||||
"lora-radio": {
|
|
||||||
"help": "Which radio to use (options: SX1272,SX1276)",
|
|
||||||
"value": "SX1276"
|
|
||||||
},
|
|
||||||
"main_stack_size": { "value": 4096 },
|
|
||||||
"lora-spi-mosi": { "value": "NC" },
|
|
||||||
"lora-spi-miso": { "value": "NC" },
|
|
||||||
"lora-spi-sclk": { "value": "NC" },
|
|
||||||
"lora-cs": { "value": "NC" },
|
|
||||||
"lora-reset": { "value": "NC" },
|
|
||||||
"lora-dio0": { "value": "NC" },
|
|
||||||
"lora-dio1": { "value": "NC" },
|
|
||||||
"lora-dio2": { "value": "NC" },
|
|
||||||
"lora-dio3": { "value": "NC" },
|
|
||||||
"lora-dio4": { "value": "NC" },
|
|
||||||
"lora-dio5": { "value": "NC" },
|
|
||||||
"lora-rf-switch-ctl1": { "value": "NC" },
|
|
||||||
"lora-rf-switch-ctl2": { "value": "NC" },
|
|
||||||
"lora-txctl": { "value": "NC" },
|
|
||||||
"lora-rxctl": { "value": "NC" },
|
|
||||||
"lora-ant-switch": { "value": "NC" },
|
|
||||||
"lora-pwr-amp-ctl": { "value": "NC" },
|
|
||||||
"lora-tcxo": { "value": "NC" },
|
|
||||||
"battery-enabled": { "value": "false" },
|
|
||||||
"battery-adc": { "value": "NC" },
|
|
||||||
"battery-ratio": { "value": "2.0f" },
|
|
||||||
"dht-enabled": { "value": "false" },
|
|
||||||
"dht-type": { "value": "DHT::DHT22" },
|
|
||||||
"dht-data": { "value": "NC" },
|
|
||||||
"hx711-enabled": { "value": "false" },
|
|
||||||
"hx711-clk": { "value": "NC" },
|
|
||||||
"hx711-data": { "value": "NC" },
|
|
||||||
"hx711-scale": { "value": "1.0f" },
|
|
||||||
"hx711-offset": { "value": 0 }
|
|
||||||
},
|
|
||||||
"target_overrides": {
|
|
||||||
"*": {
|
|
||||||
"platform.stdio-convert-newlines": true,
|
|
||||||
"platform.stdio-baud-rate": 115200,
|
|
||||||
"platform.default-serial-baud-rate": 115200,
|
|
||||||
"lora.app-port": 3,
|
|
||||||
"lora.over-the-air-activation": true,
|
|
||||||
"lora.duty-cycle-on": false,
|
|
||||||
"lora.phy": 0,
|
|
||||||
"lora.device-eui": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }",
|
|
||||||
"lora.application-eui": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }",
|
|
||||||
"lora.application-key": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }"
|
|
||||||
},
|
|
||||||
|
|
||||||
"K64F": {
|
|
||||||
"lora-spi-mosi": "D11",
|
|
||||||
"lora-spi-miso": "D12",
|
|
||||||
"lora-spi-sclk": "D13",
|
|
||||||
"lora-cs": "D10",
|
|
||||||
"lora-reset": "A0",
|
|
||||||
"lora-dio0": "D2",
|
|
||||||
"lora-dio1": "D3",
|
|
||||||
"lora-dio2": "D4",
|
|
||||||
"lora-dio3": "D5",
|
|
||||||
"lora-dio4": "D8",
|
|
||||||
"lora-dio5": "D9",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "NC",
|
|
||||||
"lora-rxctl": "NC",
|
|
||||||
"lora-ant-switch": "A4",
|
|
||||||
"lora-pwr-amp-ctl": "NC",
|
|
||||||
"lora-tcxo": "NC"
|
|
||||||
},
|
|
||||||
|
|
||||||
"DISCO_L072CZ_LRWAN1": {
|
|
||||||
"main_stack_size": 3072,
|
|
||||||
|
|
||||||
"lora-radio": "SX1276",
|
|
||||||
"lora-spi-mosi": "PA_7",
|
|
||||||
"lora-spi-miso": "PA_6",
|
|
||||||
"lora-spi-sclk": "PB_3",
|
|
||||||
"lora-cs": "PA_15",
|
|
||||||
"lora-reset": "PC_0",
|
|
||||||
"lora-dio0": "PB_4",
|
|
||||||
"lora-dio1": "PB_1",
|
|
||||||
"lora-dio2": "PB_0",
|
|
||||||
"lora-dio3": "PC_13",
|
|
||||||
"lora-dio4": "NC",
|
|
||||||
"lora-dio5": "NC",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "PC_2",
|
|
||||||
"lora-rxctl": "PA_1",
|
|
||||||
"lora-ant-switch": "NC",
|
|
||||||
"lora-pwr-amp-ctl": "PC_1",
|
|
||||||
"lora-tcxo": "PA_12"
|
|
||||||
},
|
|
||||||
|
|
||||||
"MTB_MURATA_ABZ": {
|
|
||||||
"lora-radio": "SX1276",
|
|
||||||
"lora-spi-mosi": "PA_7",
|
|
||||||
"lora-spi-miso": "PA_6",
|
|
||||||
"lora-spi-sclk": "PB_3",
|
|
||||||
"lora-cs": "PA_15",
|
|
||||||
"lora-reset": "PC_0",
|
|
||||||
"lora-dio0": "PB_4",
|
|
||||||
"lora-dio1": "PB_1",
|
|
||||||
"lora-dio2": "PB_0",
|
|
||||||
"lora-dio3": "PC_13",
|
|
||||||
"lora-dio4": "NC",
|
|
||||||
"lora-dio5": "NC",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "PC_2",
|
|
||||||
"lora-rxctl": "PA_1",
|
|
||||||
"lora-ant-switch": "NC",
|
|
||||||
"lora-pwr-amp-ctl": "PC_1",
|
|
||||||
"lora-tcxo": "PA_12"
|
|
||||||
},
|
|
||||||
|
|
||||||
"XDOT_L151CC": {
|
|
||||||
"lora-radio": "SX1272",
|
|
||||||
"lora-spi-mosi": "LORA_MOSI",
|
|
||||||
"lora-spi-miso": "LORA_MISO",
|
|
||||||
"lora-spi-sclk": "LORA_SCK",
|
|
||||||
"lora-cs": "LORA_NSS",
|
|
||||||
"lora-reset": "LORA_RESET",
|
|
||||||
"lora-dio0": "LORA_DIO0",
|
|
||||||
"lora-dio1": "LORA_DIO1",
|
|
||||||
"lora-dio2": "LORA_DIO2",
|
|
||||||
"lora-dio3": "LORA_DIO3",
|
|
||||||
"lora-dio4": "LORA_DIO4",
|
|
||||||
"lora-dio5": "NC",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "NC",
|
|
||||||
"lora-rxctl": "NC",
|
|
||||||
"lora-ant-switch": "NC",
|
|
||||||
"lora-pwr-amp-ctl": "NC",
|
|
||||||
"lora-tcxo": "NC"
|
|
||||||
},
|
|
||||||
|
|
||||||
"MTB_MTS_XDOT": {
|
|
||||||
"lora-radio": "SX1272",
|
|
||||||
"lora-spi-mosi": "LORA_MOSI",
|
|
||||||
"lora-spi-miso": "LORA_MISO",
|
|
||||||
"lora-spi-sclk": "LORA_SCK",
|
|
||||||
"lora-cs": "LORA_NSS",
|
|
||||||
"lora-reset": "LORA_RESET",
|
|
||||||
"lora-dio0": "LORA_DIO0",
|
|
||||||
"lora-dio1": "LORA_DIO1",
|
|
||||||
"lora-dio2": "LORA_DIO2",
|
|
||||||
"lora-dio3": "LORA_DIO3",
|
|
||||||
"lora-dio4": "LORA_DIO4",
|
|
||||||
"lora-dio5": "NC",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "NC",
|
|
||||||
"lora-rxctl": "NC",
|
|
||||||
"lora-ant-switch": "NC",
|
|
||||||
"lora-pwr-amp-ctl": "NC",
|
|
||||||
"lora-tcxo": "NC"
|
|
||||||
},
|
|
||||||
|
|
||||||
"LTEK_FF1705": {
|
|
||||||
"lora-radio": "SX1272",
|
|
||||||
"lora-spi-mosi": "LORA_MOSI",
|
|
||||||
"lora-spi-miso": "LORA_MISO",
|
|
||||||
"lora-spi-sclk": "LORA_SCK",
|
|
||||||
"lora-cs": "LORA_NSS",
|
|
||||||
"lora-reset": "LORA_RESET",
|
|
||||||
"lora-dio0": "LORA_DIO0",
|
|
||||||
"lora-dio1": "LORA_DIO1",
|
|
||||||
"lora-dio2": "LORA_DIO2",
|
|
||||||
"lora-dio3": "LORA_DIO3",
|
|
||||||
"lora-dio4": "LORA_DIO4",
|
|
||||||
"lora-dio5": "NC",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "NC",
|
|
||||||
"lora-rxctl": "NC",
|
|
||||||
"lora-ant-switch": "NC",
|
|
||||||
"lora-pwr-amp-ctl": "NC",
|
|
||||||
"lora-tcxo": "NC"
|
|
||||||
},
|
|
||||||
|
|
||||||
"MTS_MDOT_F411RE": {
|
|
||||||
"lora-radio": "SX1272",
|
|
||||||
"lora-spi-mosi": "LORA_MOSI",
|
|
||||||
"lora-spi-miso": "LORA_MISO",
|
|
||||||
"lora-spi-sclk": "LORA_SCK",
|
|
||||||
"lora-cs": "LORA_NSS",
|
|
||||||
"lora-reset": "LORA_RESET",
|
|
||||||
"lora-dio0": "LORA_DIO0",
|
|
||||||
"lora-dio1": "LORA_DIO1",
|
|
||||||
"lora-dio2": "LORA_DIO2",
|
|
||||||
"lora-dio3": "LORA_DIO3",
|
|
||||||
"lora-dio4": "LORA_DIO4",
|
|
||||||
"lora-dio5": "LORA_DIO5",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "LORA_TXCTL",
|
|
||||||
"lora-rxctl": "LORA_RXCTL",
|
|
||||||
"lora-ant-switch": "NC",
|
|
||||||
"lora-pwr-amp-ctl": "NC",
|
|
||||||
"lora-tcxo": "NC"
|
|
||||||
},
|
|
||||||
|
|
||||||
"MTB_ADV_WISE_1510": {
|
|
||||||
"lora-radio": "SX1276",
|
|
||||||
"lora-spi-mosi": "SPI_RF_MOSI",
|
|
||||||
"lora-spi-miso": "SPI_RF_MISO",
|
|
||||||
"lora-spi-sclk": "SPI_RF_SCK",
|
|
||||||
"lora-cs": "SPI_RF_CS",
|
|
||||||
"lora-reset": "SPI_RF_RESET",
|
|
||||||
"lora-dio0": "DIO0",
|
|
||||||
"lora-dio1": "DIO1",
|
|
||||||
"lora-dio2": "DIO2",
|
|
||||||
"lora-dio3": "DIO3",
|
|
||||||
"lora-dio4": "DIO4",
|
|
||||||
"lora-dio5": "DIO5",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "NC",
|
|
||||||
"lora-rxctl": "NC",
|
|
||||||
"lora-ant-switch": "ANT_SWITCH",
|
|
||||||
"lora-pwr-amp-ctl": "NC",
|
|
||||||
"lora-tcxo": "NC"
|
|
||||||
},
|
|
||||||
|
|
||||||
"MTB_RAK811": {
|
|
||||||
"lora-radio": "SX1276",
|
|
||||||
"lora-spi-mosi": "SPI_RF_MOSI",
|
|
||||||
"lora-spi-miso": "SPI_RF_MISO",
|
|
||||||
"lora-spi-sclk": "SPI_RF_SCK",
|
|
||||||
"lora-cs": "SPI_RF_CS",
|
|
||||||
"lora-reset": "SPI_RF_RESET",
|
|
||||||
"lora-dio0": "DIO0",
|
|
||||||
"lora-dio1": "DIO1",
|
|
||||||
"lora-dio2": "DIO2",
|
|
||||||
"lora-dio3": "DIO3",
|
|
||||||
"lora-dio4": "DIO4",
|
|
||||||
"lora-dio5": "NC",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "ANT_CTX_PA",
|
|
||||||
"lora-rxctl": "ANT_CRX_RX",
|
|
||||||
"lora-ant-switch": "NC",
|
|
||||||
"lora-pwr-amp-ctl": "NC",
|
|
||||||
"lora-tcxo": "RF_TCXO_EN",
|
|
||||||
"battery-enabled": true,
|
|
||||||
"battery-adc": "PA_2",
|
|
||||||
"dht-enabled": true,
|
|
||||||
"dht-data": "PA_1",
|
|
||||||
"dht-type": "DHT::DHT22"
|
|
||||||
},
|
|
||||||
|
|
||||||
"NUCLEO_L073RZ": {
|
|
||||||
"main_stack_size": 1024,
|
|
||||||
"target.lpticker_lptim": 0,
|
|
||||||
"target.clock_source": "USE_PLL_HSI",
|
|
||||||
"lora.duty-cycle-on": false,
|
|
||||||
"tx-timer": 600000,
|
|
||||||
"lora-radio": "SX1272",
|
|
||||||
"lora-spi-mosi": "D11",
|
|
||||||
"lora-spi-miso": "D12",
|
|
||||||
"lora-spi-sclk": "D13",
|
|
||||||
"lora-cs": "D10",
|
|
||||||
"lora-reset": "A0",
|
|
||||||
"lora-dio0": "D2",
|
|
||||||
"lora-dio1": "D3",
|
|
||||||
"lora-dio2": "D4",
|
|
||||||
"lora-dio3": "D5",
|
|
||||||
"lora-dio4": "NC",
|
|
||||||
"lora-dio5": "NC",
|
|
||||||
"lora-rf-switch-ctl1": "NC",
|
|
||||||
"lora-rf-switch-ctl2": "NC",
|
|
||||||
"lora-txctl": "NC",
|
|
||||||
"lora-rxctl": "NC",
|
|
||||||
"lora-ant-switch": "A4",
|
|
||||||
"lora-pwr-amp-ctl": "NC",
|
|
||||||
"lora-tcxo": "NC",
|
|
||||||
"battery-enabled": true,
|
|
||||||
"battery-adc": "A1",
|
|
||||||
"battery-ratio": "2.0f",
|
|
||||||
"dht-enabled": true,
|
|
||||||
"dht-data": "D8",
|
|
||||||
"dht-type": "DHT::DHT22",
|
|
||||||
"hx711-enabled": true,
|
|
||||||
"hx711-clk": "D7",
|
|
||||||
"hx711-data": "D6",
|
|
||||||
"hx711-scale": "21000.0f",
|
|
||||||
"hx711-offset": 59600
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_lora_config.h\""]
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r",
|
"ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r",
|
||||||
"-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r",
|
"-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r",
|
||||||
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
|
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
|
||||||
"-Wl,-n", "--specs=nano.specs"]
|
"-Wl,-n", "--specs=nano.specs", "-u _printf_float"]
|
||||||
},
|
},
|
||||||
"ARMC6": {
|
"ARMC6": {
|
||||||
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Oz",
|
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Oz",
|
||||||
|
|||||||
Executable
+47
@@ -0,0 +1,47 @@
|
|||||||
|
#!/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;
|
||||||
Reference in New Issue
Block a user