work1

Dependencies:   mbed MAX44009 mbed-os Si7021

Revision:
0:d3e390d62607
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AppLora.cpp	Wed May 27 11:37:29 2020 +0000
@@ -0,0 +1,377 @@
+
+#include <stdio.h>
+
+#include "lorawan/LoRaWANInterface.h"
+#include "lorawan/system/lorawan_data_structures.h"
+#include "events/EventQueue.h"
+
+#include "mbed.h"
+#include "AppLora.h"
+#include "AppMain.h"
+#include "tools.h"
+
+// Application helpers
+//#include "trace_helper.h"
+#include "lora_radio_helper.h"
+#include "hal/pinmap.h"
+#include "PeripheralPins.h"
+#include "board/PowerManager.h"
+
+#include "mbed_trace.h"
+#define TRACE_GROUP "lora"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "tools.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+
+using namespace events;
+EventQueue * AppLora::_queue;
+Callback<void(AppLora::EVENT)> AppLora::_lora_callback;
+DigitalInOut AppLora::_txco(LORA_TXCO);
+
+// Max payload size can be LORAMAC_PHY_MAXPAYLOAD.
+// This example only communicates with much shorter messages (<30 bytes).
+// If longer messages are used, these buffers must be changed accordingly.
+uint8_t tx_buffer[30];
+uint8_t rx_buffer[30];
+
+
+/**
+ * Maximum number of retries for CONFIRMED messages before giving up
+ */
+#define CONFIRMED_MSG_RETRY_COUNTER     3
+
+/**
+ * Constructing Mbed LoRaWANInterface and passing it down the radio object.
+ */
+static LoRaWANInterface lorawan(radio);
+
+/**
+ * Application specific callbacks
+ */
+lorawan_app_callbacks_t AppLora::_callbacks;
+
+void AppLora::_pin_active_mode(void){
+
+    // enable MOSI pin
+    pinmap_pinout(LORA_SPI_MOSI, PinMap_SPI_MOSI);
+    pinmap_pinout(LORA_SPI_MISO, PinMap_SPI_MISO);
+    pinmap_pinout(LORA_SPI_SCLK, PinMap_SPI_SCLK);
+
+    // enable high precision oscillator (around 500uA)
+    _txco.mode(PullNone);
+    _txco = 1;
+    _txco.output();
+}
+
+void AppLora::_pin_lowpower_mode(void){
+    DigitalIn lora_spi_miso(LORA_SPI_MISO);
+    DigitalIn lora_spi_mosi(LORA_SPI_MOSI);
+
+    // That was a big mistake that consume 30µA
+    // It must be corrected on tag
+    //DigitalIn lora_spi_cs(SPI_MOSI);
+    //lora_spi_cs.mode(PullNone);
+
+    lora_spi_miso.mode(PullNone);
+    lora_spi_mosi.mode(PullNone);
+#if 0
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+
+    // for whatever reason the mosi pin draw approximatly 300uA.
+    // So it need to be disabled when loRa is not used
+    // disable LORA_MOSI_SPI
+    GPIO_InitStruct.Pin =  GPIO_PIN_6 | GPIO_PIN_7 /* GPIO_PIN_7 | | GPIO_PIN_15*/;
+    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin =  GPIO_PIN_3;
+    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+#endif
+
+    // disable high precision oscillator
+    _txco = 0;
+    _txco.input();
+}
+
+void AppLora::_enter_lowpower_mode(void){
+    _pin_lowpower_mode();
+    PowerManager *pm= PowerManager::get_instance();
+    pm->sleep_mode();
+}
+
+void AppLora::_enter_active_mode(void){
+    PowerManager *pm= PowerManager::get_instance();
+    pm->run_mode();
+    _pin_active_mode();
+}
+
+void AppLora::initialize(EventQueue *queue)
+{
+    _queue = queue;
+
+    _enter_active_mode();
+
+    tr_debug("setting voltage to 3V");
+    // setup tracing
+    //setup_trace();
+
+    // Initialize LoRaWAN stack
+    if (lorawan.initialize(_queue) != LORAWAN_STATUS_OK) {
+        tr_err("LoRa initialization failed!");
+        //return -1;
+    }
+
+    tr_info("mbed LoRaWANStack initialized");
+
+    // prepare application callbacks
+    _callbacks.events = mbed::callback(AppLora::_lora_event_handler);
+    lorawan.add_app_callbacks(&_callbacks);
+
+    // Set number of retries in case of CONFIRMED messages
+    if (lorawan.set_confirmed_msg_retries(CONFIRMED_MSG_RETRY_COUNTER)
+                                          != LORAWAN_STATUS_OK) {
+        tr_err("set_confirmed_msg_retries failed!");
+        //return -1;
+    }
+
+    tr_debug("confirmed message retries : %d", CONFIRMED_MSG_RETRY_COUNTER);
+
+    // Enable adaptive data rate
+    /*
+    if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) {
+        PRINT("\r\n enable_adaptive_datarate failed! \r\n");
+        //return -1;
+    }
+    */
+
+    //PRINT("\r\n Adaptive data  rate (ADR) - Enabled \r\n");
+
+    _enter_lowpower_mode();
+
+}
+u32 AppLora::get_random(void){
+    u32 rand;
+    _enter_active_mode();
+    rand = radio.random();
+    _enter_lowpower_mode();
+    return rand;
+
+}
+
+u8 AppLora::get_next_transmission_max_size(void){
+    /*
+     * find a better way to get the max payload size
+     */
+#if 0
+    lorawan_tx_metadata meta;
+    lorawan.get_tx_metadata(meta);
+    return meta.max_payload;
+#else
+    return 51; // minimum payload size
+#endif
+
+
+}
+
+void AppLora::connect(void){
+    lorawan_status_t retcode;
+    _enter_active_mode();
+    retcode = lorawan.connect();
+
+    if (retcode == LORAWAN_STATUS_OK ||
+        retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) {
+    } else {
+        tr_err("connection error, code = %d", retcode);
+        _enter_lowpower_mode();
+        _call_callback(AppLora::EVENT_CONNECTION_ERROR);
+        //return -1;
+        return;
+    }
+
+    tr_info("connection - in progress...");
+}
+
+void AppLora::disconnect(void){
+    lorawan.cancel_sending();
+    lorawan.disconnect();
+}
+
+/**
+ * Sends a message to the Network Server
+ */
+s16 AppLora::send_message(u8 *data, u8 data_size, u8 app_port, bool confirmed)
+{
+    s16 retcode;
+    static u8 would_block_error_count = 0;
+
+    int flags = MSG_UNCONFIRMED_FLAG;
+	tr_info("sending message");
+    tr_debug("\t confirmed: %d", confirmed);
+    tr_debug("\t port: 0x%02x", app_port);
+    tr_debug("\t size: %d", data_size);
+    tr_info("\t data: ");
+    tools_print_to_hex(data, data_size);
+    if(confirmed){
+        flags = MSG_CONFIRMED_FLAG;
+    }
+    _enter_active_mode();
+
+    retcode = lorawan.send(app_port, data, data_size, flags);
+    if(retcode < 0){
+        /*
+         * LoRa error code are between -1000 and -1024
+         * -(retcode+1000) convert the error in a number between
+         *  1 and 24
+         *
+         * Then the value 1 is saved @ the virtual address va between 1 and 24
+         */
+        tr_warn("\t error : %d", retcode);
+    }
+
+    if(retcode == LORAWAN_STATUS_WOULD_BLOCK){
+        ++would_block_error_count;
+        // Reset only if this error appear three time in a row
+        // Because in some case this error can appear during the join and this
+        // is the expected behaviour
+        if(would_block_error_count > 2){
+            NVIC_SystemReset();
+        }
+    }
+    else if(retcode >= 0){
+        would_block_error_count = 0;
+    }
+
+    return retcode;
+
+}
+
+/**
+ * Receive a message from the Network Server
+ */
+s16 AppLora::get_rx_message(u8 *data, u16 data_size, u8 &app_port)
+{
+    s16 received_size;
+    int flags;
+    received_size = lorawan.receive(data, data_size, app_port, flags);
+
+    if (received_size < 0) {
+        tr_err("receive() - Error code %d", received_size);
+    //    return;
+    }
+	else{
+	    tr_info("received message");
+        tr_debug("\t flags: %d", flags);
+        tr_debug("\t port: %d", app_port);
+        tr_debug("\t max size: %d", data_size);
+        tr_debug("\t received size: %d", received_size);
+        tr_info("\t data: ");
+        tools_print_to_hex(data, received_size);
+	}
+    return received_size;
+
+}
+
+void AppLora::_send_empty_uplink(void){
+    int retcode;
+    _enter_active_mode();
+    //wait(0.05);
+    wait_us(50000);
+    // we could add more information in this frame
+    retcode = lorawan.send(1, NULL, 0, MSG_CONFIRMED_FLAG);
+    if (retcode < 0) {
+        tr_err("uplink send() - Error code %d", retcode);
+        _enter_lowpower_mode();
+
+    //    return;
+    }
+    //_enter_lowpower_mode();
+
+}
+
+void AppLora::set_lora_callback(Callback<void(AppLora::EVENT)> lora_callback){
+    _lora_callback = lora_callback;
+}
+
+void AppLora::_call_callback(AppLora::EVENT lora_event){
+    if(_lora_callback){
+        _lora_callback(lora_event);
+    }
+}
+/**
+ * Event handler
+ */
+void AppLora::_lora_event_handler(lorawan_event_t event)
+{
+    switch (event) {
+        case CONNECTED:
+            tr_info("connection - successful");
+            _enter_lowpower_mode();
+            _call_callback(AppLora::EVENT_CONNECTED);
+
+            break;
+        case DISCONNECTED:
+            //AppLora::_queue->break_dispatch();
+            tr_info("disconnected successfully");
+            _enter_lowpower_mode();
+            _call_callback(AppLora::EVENT_DISCONNECTED);
+            break;
+        case TX_DONE:
+            tr_info("message sent to network server");
+            _enter_lowpower_mode();
+            _call_callback(AppLora::EVENT_TX_DONE);
+            break;
+        case UPLINK_REQUIRED:
+            // Uplink are requested when the pending bit is set
+            // or when more downlink messages are waiting
+            // ACK seems to be handled directly by the stack
+            tr_info("LoRaStack requesting uplink");
+            _send_empty_uplink();
+            _call_callback(AppLora::EVENT_UPLINK_REQUIERED);
+            break;
+        case TX_TIMEOUT:
+        case TX_ERROR:
+        case TX_CRYPTO_ERROR:
+        case TX_SCHEDULING_ERROR:
+            tr_err("transmission error - event code = %d", event);
+            _enter_lowpower_mode();
+            _call_callback(AppLora::EVENT_TX_ERROR);
+            break;
+        case RX_DONE:
+            tr_info("received message from network server");
+            AppMain::incoming_lora_message_callback();
+            _enter_lowpower_mode();
+            _call_callback(AppLora::EVENT_RX_DONE);
+            //receive_message();
+            break;
+        case RX_TIMEOUT:
+        case RX_ERROR:
+            tr_err("error in reception - code = %d", event);
+            _enter_lowpower_mode();
+            _call_callback(AppLora::EVENT_RX_ERROR);
+            break;
+        case JOIN_FAILURE:
+            tr_err("OTAA failed - check keys");
+            _enter_lowpower_mode();
+            _call_callback(AppLora::EVENT_JOIN_FAILURE);
+            break;
+        default:
+            MBED_ASSERT("Unknown Event");
+            _enter_lowpower_mode();
+    }
+}
+
+// EOF
+
+