├── .gitignore ├── CMakeLists.txt ├── Kconfig.projbuild ├── examples ├── FactoryTest │ ├── Factory_Test_Wifi_LoRa32_V2 │ │ ├── Factory_Test_Wifi_LoRa32_V2.ino │ │ └── images.h │ ├── Factory_Test_Wireless_Stick │ │ ├── Factory_Test_Wireless_Stick.ino │ │ └── images.h │ └── Factory_Test_Wireless_Stick_Lite │ │ ├── Factory_Test_Wireless_Stick_Lite.ino │ │ └── images.h ├── OTAA │ └── OTAA.ino ├── OTAA_Battery_power │ └── OTAA_Battery_power.ino ├── OTAA_LED │ └── OTAA_LED.ino ├── OTAA_OLED │ └── OTAA_OLED.ino ├── OTAA_OLED_Interrupt_CLASS_A │ └── OTAA_OLED_Interrupt_CLASS_A.ino ├── OTAA_OLED_interrupt_CLASS_C │ └── OTAA_OLED_interrupt_CLASS_C.ino ├── Sensor │ └── LoRaWAN_HDC1080 │ │ └── LoRaWAN_HDC1080.ino ├── WiFi_LoRaWAN │ └── WiFi_LoRaWAN.ino └── pingpong │ └── pingpong.ino ├── idf_component.yml ├── img ├── 01.png ├── 02.png └── 03.png ├── library.properties ├── readme.md └── src ├── CMakeLists.txt ├── Commissioning.h ├── ESP32_LoRaWAN.cpp ├── ESP32_LoRaWAN.h ├── LoRaMac.c ├── LoRaMac.h ├── LoRaMacConfirmQueue.c ├── LoRaMacConfirmQueue.h ├── LoRaMacCrypto.c ├── LoRaMacCrypto.h ├── LoRaMacTest.h ├── Mcu.S ├── Mcu.h ├── OLEDDisplay.cpp ├── OLEDDisplay.h ├── OLEDDisplayFonts.h ├── OLEDDisplayUi.cpp ├── OLEDDisplayUi.h ├── RTE_Components.h ├── SSD1306.h ├── SSD1306Wire.h ├── aes.c ├── aes.h ├── board-config.h ├── board.c ├── board.h ├── cmac.c ├── cmac.h ├── debug.h ├── delay.c ├── delay.h ├── fifo.c ├── fifo.h ├── gpio-board.c ├── gpio-board.h ├── gpio.c ├── gpio.h ├── lorawan_spi.h ├── pinName-board.h ├── pinName-ioe.h ├── radio.h ├── region ├── Region.c ├── Region.h ├── RegionAS923.c ├── RegionAS923.h ├── RegionAU915.c ├── RegionAU915.h ├── RegionCN470.c ├── RegionCN470.h ├── RegionCN779.c ├── RegionCN779.h ├── RegionCommon.c ├── RegionCommon.h ├── RegionEU433.c ├── RegionEU433.h ├── RegionEU868.c ├── RegionEU868.h ├── RegionIN865.c ├── RegionIN865.h ├── RegionKR920.c ├── RegionKR920.h ├── RegionLA915.c ├── RegionLA915.h ├── RegionUS915-Hybrid.c ├── RegionUS915-Hybrid.h ├── RegionUS915.c └── RegionUS915.h ├── rtc-board.S ├── rtc-board.h ├── sensor ├── HDC1080.cpp └── HDC1080.h ├── sx1276-board.c ├── sx1276-board.h ├── sx1276.c ├── sx1276.h ├── sx1276Regs-Fsk.h ├── sx1276Regs-LoRa.h ├── timer.S ├── timer.h ├── utilities.c └── utilities.h /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vscode 3 | *~ 4 | .*.swp 5 | .*.swo 6 | /build 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(srcs 2 | src/LoRaMac.c 3 | src/aes.c 4 | src/LoRaMacCrypto.c 5 | src/Mcu.S 6 | src/gpio.c 7 | src/board.c 8 | src/delay.c 9 | src/gpio-board.c 10 | src/cmac.c 11 | src/OLEDDisplay.cpp 12 | src/fifo.c 13 | src/timer.S 14 | src/region/RegionUS915-Hybrid.c 15 | src/region/RegionAU915.c 16 | src/region/RegionCN470.c 17 | src/region/RegionAS923.c 18 | src/region/Region.c 19 | src/region/RegionCN779.c 20 | src/region/RegionLA915.c 21 | src/region/RegionEU868.c 22 | src/region/RegionKR920.c 23 | src/region/RegionEU433.c 24 | src/region/RegionCommon.c 25 | src/region/RegionIN865.c 26 | src/region/RegionUS915.c 27 | src/rtc-board.S 28 | src/sensor/HDC1080.cpp 29 | src/ESP32_LoRaWAN.cpp 30 | src/utilities.c 31 | src/OLEDDisplayUi.cpp 32 | src/sx1276-board.c 33 | src/sx1276.c 34 | src/LoRaMacConfirmQueue.c 35 | ) 36 | 37 | set(includedirs 38 | src 39 | src/region 40 | src/sensor 41 | ) 42 | 43 | set(priv_includes ) 44 | set(requires arduino) 45 | set(priv_requires ) 46 | 47 | idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires}) 48 | 49 | function(maybe_add_component component_name) 50 | idf_build_get_property(components BUILD_COMPONENTS) 51 | if (${component_name} IN_LIST components) 52 | idf_component_get_property(lib_name ${component_name} COMPONENT_LIB) 53 | target_link_libraries(${COMPONENT_LIB} PUBLIC ${lib_name}) 54 | endif() 55 | endfunction() 56 | 57 | maybe_add_component(arduino) 58 | 59 | target_compile_options(${COMPONENT_TARGET} PUBLIC 60 | -DESP32 -DLORAWAN_PREAMBLE_LENGTH=${CONFIG_LORAWAN_PREAMBLE_LENGTH} 61 | ) 62 | -------------------------------------------------------------------------------- /Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "LoRaWAN library for ESP32 + LoRa boards made by heltec" 2 | 3 | config LORAWAN_PREAMBLE_LENGTH 4 | int "LoRaWAN preamble length" 5 | default 8 6 | help 7 | The length of the LoRaWAN premable. 8 | 9 | endmenu 10 | -------------------------------------------------------------------------------- /examples/FactoryTest/Factory_Test_Wifi_LoRa32_V2/images.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGES_H 2 | #define IMAGES_H 3 | 4 | #define logo_width 128 5 | #define logo_height 53 6 | const static char logo_bits[] = { 7 | 8 | 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xF0, 0x03, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0xC0, 0x07, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF0, 0x1F, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0xE0, 0x1F, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0xE0, 0x3F, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0xF8, 0x3F, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0xE0, 0x1F, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0xFC, 0x1F, 23 | 0x80, 0xFF, 0x8F, 0x7F, 0xC0, 0xFF, 0x7F, 0xC0, 0xFF, 0x03, 0xC0, 0x3F, 24 | 0xF0, 0x1F, 0xFC, 0x1F, 0xE0, 0xFF, 0x87, 0x3F, 0xC0, 0xFF, 0x7F, 0xF0, 25 | 0xFF, 0x01, 0xF8, 0xFF, 0xF0, 0x0F, 0xFC, 0x1F, 0xE0, 0xFF, 0x87, 0x3F, 26 | 0xE0, 0xFF, 0x7F, 0xF8, 0xFF, 0x01, 0xFE, 0xFF, 0xF8, 0x0F, 0xFE, 0x0F, 27 | 0xF0, 0xFF, 0x87, 0x3F, 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0x01, 0xFF, 0xFF, 28 | 0xF8, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xC7, 0x3F, 0xE0, 0xFF, 0x3F, 0xFC, 29 | 0xFF, 0x81, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xC3, 0x1F, 30 | 0xE0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0x0F, 31 | 0xF8, 0xFF, 0xC3, 0x1F, 0xE0, 0xFF, 0x3F, 0xFC, 0xFF, 0xE0, 0xFF, 0x7F, 32 | 0xFC, 0xFF, 0xFF, 0x07, 0xF8, 0x03, 0xC0, 0x1F, 0x00, 0xFE, 0x01, 0xFE, 33 | 0x00, 0xF0, 0x3F, 0x70, 0xFC, 0xFF, 0xFF, 0x07, 0xF8, 0x03, 0xE0, 0x0F, 34 | 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xF0, 0x1F, 0x60, 0xFC, 0xFF, 0xFF, 0x07, 35 | 0xF8, 0x03, 0xE0, 0x0F, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xF0, 0x07, 0x20, 36 | 0xFE, 0xFF, 0xFF, 0x07, 0xFC, 0xFF, 0xE1, 0x0F, 0x00, 0xFF, 0x00, 0xFF, 37 | 0x7F, 0xF8, 0x07, 0x00, 0xFE, 0x83, 0xFF, 0x03, 0xFC, 0xFF, 0xF1, 0x0F, 38 | 0x00, 0x7F, 0x00, 0xFF, 0x7F, 0xF8, 0x03, 0x00, 0xFE, 0x83, 0xFF, 0x03, 39 | 0xFC, 0xFF, 0xF0, 0x07, 0x00, 0x7F, 0x00, 0xFF, 0x7F, 0xFC, 0x03, 0x00, 40 | 0xFE, 0x81, 0xFF, 0x03, 0xFC, 0xFF, 0xF0, 0x07, 0x00, 0x7F, 0x00, 0xFF, 41 | 0x3F, 0xFC, 0x03, 0x00, 0xFF, 0xC1, 0xFF, 0x01, 0xFE, 0xFF, 0xF0, 0x07, 42 | 0x80, 0x3F, 0x80, 0xFF, 0x3F, 0xFC, 0x03, 0x00, 0xFF, 0xC1, 0xFF, 0x01, 43 | 0xFE, 0xFF, 0xF8, 0x07, 0x80, 0x3F, 0x80, 0xFF, 0x3F, 0xFC, 0x03, 0x10, 44 | 0xFF, 0xC1, 0xFF, 0x01, 0xFE, 0x00, 0xF8, 0x03, 0x80, 0x3F, 0x80, 0x3F, 45 | 0x00, 0xFC, 0x03, 0x0C, 0xFF, 0xC0, 0xFF, 0x01, 0xFF, 0x00, 0xF8, 0x03, 46 | 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0xFC, 0x07, 0x0E, 0xFF, 0xE0, 0xFF, 0x00, 47 | 0x7F, 0x00, 0xF8, 0x03, 0xC0, 0x1F, 0xC0, 0x3F, 0x00, 0xFC, 0xFF, 0x0F, 48 | 0xFF, 0xE0, 0xFF, 0x00, 0xFF, 0x7F, 0xFC, 0xFF, 0xC1, 0x1F, 0xC0, 0xFF, 49 | 0x1F, 0xFC, 0xFF, 0x0F, 0x7F, 0xE0, 0xFF, 0x00, 0xFF, 0x3F, 0xFC, 0xFF, 50 | 0xC1, 0x1F, 0xC0, 0xFF, 0x0F, 0xF8, 0xFF, 0x07, 0x7E, 0xE0, 0xFF, 0x80, 51 | 0xFF, 0x3F, 0xFC, 0xFF, 0xE0, 0x1F, 0xC0, 0xFF, 0x0F, 0xF8, 0xFF, 0x07, 52 | 0x7C, 0xF0, 0x7F, 0x80, 0xFF, 0x3F, 0xFE, 0xFF, 0xE0, 0x0F, 0xE0, 0xFF, 53 | 0x0F, 0xF0, 0xFF, 0x07, 0xF8, 0xF0, 0x7F, 0x80, 0xFF, 0x1F, 0xFE, 0xFF, 54 | 0xE0, 0x0F, 0xE0, 0xFF, 0x0F, 0xE0, 0xFF, 0x07, 0xE0, 0xF0, 0x7F, 0x80, 55 | 0xFF, 0x1F, 0xFE, 0xFF, 0xE0, 0x0F, 0xE0, 0xFF, 0x07, 0x80, 0xFF, 0x03, 56 | 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x3C, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x8F, 0xF7, 0xFF, 0x7C, 62 | 0xBC, 0xC7, 0xF3, 0xFF, 0xFC, 0xBC, 0x07, 0x00, 0x00, 0xFC, 0x1F, 0x00, 63 | 0x8F, 0x73, 0xFF, 0xFE, 0xBE, 0xC7, 0xFB, 0xFF, 0xFE, 0xBD, 0x03, 0x00, 64 | 0x00, 0xFC, 0x1F, 0x80, 0x8F, 0x73, 0xFF, 0xEF, 0xFE, 0xE7, 0xFB, 0x77, 65 | 0xEF, 0xFD, 0x03, 0x00, 0x00, 0xFC, 0x1F, 0x80, 0xDF, 0x7B, 0x9C, 0xE7, 66 | 0xFE, 0xF7, 0xE3, 0x71, 0xE7, 0xFD, 0x03, 0x00, 0x00, 0xFC, 0x0F, 0xC0, 67 | 0xDF, 0x79, 0x9E, 0xE3, 0xFE, 0xF3, 0xE3, 0x78, 0xE7, 0xFF, 0x03, 0x00, 68 | 0x00, 0xFC, 0x0F, 0xE0, 0xDF, 0x39, 0x8E, 0xF3, 0xFF, 0xFB, 0xE7, 0xF8, 69 | 0xE7, 0xFE, 0x01, 0x00, 0x00, 0xFC, 0x0F, 0xE0, 0xDF, 0x3F, 0x8E, 0x7F, 70 | 0xFF, 0xFF, 0xE7, 0x38, 0x7F, 0xEE, 0x01, 0x00, 0x00, 0xF8, 0x0F, 0x70, 71 | 0xDC, 0x1F, 0x0E, 0x3F, 0xFF, 0x9D, 0xF7, 0x38, 0x3F, 0xEF, 0x01, 0x00, 72 | 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 73 | 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; 79 | 80 | const char activeSymbol[] PROGMEM = { 81 | B00000000, 82 | B00000000, 83 | B00011000, 84 | B00100100, 85 | B01000010, 86 | B01000010, 87 | B00100100, 88 | B00011000 89 | }; 90 | 91 | const char inactiveSymbol[] PROGMEM = { 92 | B00000000, 93 | B00000000, 94 | B00000000, 95 | B00000000, 96 | B00011000, 97 | B00011000, 98 | B00000000, 99 | B00000000 100 | }; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /examples/FactoryTest/Factory_Test_Wireless_Stick/Factory_Test_Wireless_Stick.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Arduino.h" 3 | #include "WiFi.h" 4 | #include "images.h" 5 | 6 | #define USER_KEY 0 7 | #define YOUR_SSID "your ssid" 8 | #define YOUR_PASSWORD "your password" 9 | 10 | #define RF_FREQUENCY 868000000 // Hz 11 | 12 | #define TX_OUTPUT_POWER 14 // dBm 13 | 14 | #define LORA_BANDWIDTH 0 // [0: 125 kHz, 15 | // 1: 250 kHz, 16 | // 2: 500 kHz, 17 | // 3: Reserved] 18 | #define LORA_SPREADING_FACTOR 7 // [SF7..SF12] 19 | #define LORA_CODINGRATE 1 // [1: 4/5, 20 | // 2: 4/6, 21 | // 3: 4/7, 22 | // 4: 4/8] 23 | #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx 24 | #define LORA_SYMBOL_TIMEOUT 0 // Symbols 25 | #define LORA_FIX_LENGTH_PAYLOAD_ON false 26 | #define LORA_IQ_INVERSION_ON false 27 | 28 | 29 | #define RX_TIMEOUT_VALUE 1000 30 | #define BUFFER_SIZE 30 // Define the payload size here 31 | 32 | char txpacket[BUFFER_SIZE]; 33 | char rxpacket[BUFFER_SIZE]; 34 | 35 | static RadioEvents_t RadioEvents; 36 | void OnTxDone( void ); 37 | void OnTxTimeout( void ); 38 | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); 39 | 40 | typedef enum 41 | { 42 | STATUS_LOWPOWER, 43 | STATUS_RX, 44 | STATUS_TX 45 | }States_t; 46 | 47 | 48 | int16_t txNumber; 49 | States_t state; 50 | bool sleepMode = false; 51 | int16_t Rssi,rxSize; 52 | 53 | uint32_t license[4] = {0xD5397DF0, 0x8573F814, 0x7A38C73D, 0x48E68607}; 54 | 55 | void WIFISetUp(void) 56 | { 57 | // Set WiFi to station mode and disconnect from an AP if it was previously connected 58 | WiFi.disconnect(true); 59 | delay(100); 60 | WiFi.mode(WIFI_STA); 61 | WiFi.setAutoConnect(true); 62 | WiFi.begin(YOUR_SSID,YOUR_PASSWORD);//fill in "Your WiFi SSID","Your Password" 63 | delay(100); 64 | Display.clear(); 65 | byte count = 0; 66 | while(WiFi.status() != WL_CONNECTED && count < 10) 67 | { 68 | count ++; 69 | delay(500); 70 | Display.drawString(0, 0, "Connecting..."); 71 | Display.display(); 72 | } 73 | 74 | if(WiFi.status() == WL_CONNECTED) 75 | { 76 | Display.drawString(0, 9, "OK"); 77 | Display.display(); 78 | delay(1000); 79 | Display.clear(); 80 | } 81 | else 82 | { 83 | Display.drawString(0, 9, "Failed"); 84 | Display.display(); 85 | delay(1000); 86 | Display.clear(); 87 | } 88 | } 89 | 90 | void WIFIScan(unsigned int value) 91 | { 92 | unsigned int i; 93 | WiFi.mode(WIFI_STA); 94 | 95 | for(i=0;i>32));//print High 2 bytes 150 | Serial.printf("%08X\n",(uint32_t)chipid);//print Low 4bytes. 151 | delay(100); 152 | 153 | SPI.begin(SCK,MISO,MOSI,SS); 154 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 155 | 156 | pinMode(Vext,OUTPUT); 157 | digitalWrite(Vext,LOW); 158 | delay(50); 159 | Display.init(); 160 | 161 | delay(300); 162 | Display.clear(); 163 | 164 | WIFISetUp(); 165 | WiFi.disconnect(); //重新初始化WIFI 166 | WiFi.mode(WIFI_STA); 167 | delay(100); 168 | 169 | WIFIScan(1); 170 | 171 | txNumber=0; 172 | Rssi=0; 173 | 174 | RadioEvents.TxDone = OnTxDone; 175 | RadioEvents.TxTimeout = OnTxTimeout; 176 | RadioEvents.RxDone = OnRxDone; 177 | 178 | Radio.Init( &RadioEvents ); 179 | Radio.SetChannel( RF_FREQUENCY ); 180 | Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, 181 | LORA_SPREADING_FACTOR, LORA_CODINGRATE, 182 | LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, 183 | true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); 184 | 185 | Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, 186 | LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, 187 | LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 188 | 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); 189 | state=STATUS_TX; 190 | pinMode(USER_KEY,INPUT_PULLUP); 191 | attachInterrupt(USER_KEY,interrupt,FALLING); 192 | } 193 | 194 | 195 | void loop() 196 | { 197 | switch(state) 198 | { 199 | case STATUS_TX: 200 | delay(1000); 201 | txNumber++; 202 | sprintf(txpacket,"%s","hello"); 203 | sprintf(txpacket+strlen(txpacket),"%d",txNumber); 204 | sprintf(txpacket+strlen(txpacket),"%s"," Rssi : "); 205 | sprintf(txpacket+strlen(txpacket),"%d",Rssi); 206 | 207 | Serial.printf("\r\nsending packet \"%s\" , length %d\r\n",txpacket, strlen(txpacket)); 208 | 209 | Radio.Send( (uint8_t *)txpacket, strlen(txpacket) ); 210 | state=STATUS_LOWPOWER; 211 | break; 212 | case STATUS_RX: 213 | Serial.println("into RX mode"); 214 | Radio.Rx( 0 ); 215 | state=STATUS_LOWPOWER; 216 | break; 217 | case STATUS_LOWPOWER: 218 | LoRaWAN.sleep(CLASS_C,0); 219 | if(deepsleepflag) 220 | { 221 | delay(200); 222 | LoRaWAN.sleep(CLASS_C,0); 223 | Serial.println("lowpower"); 224 | Radio.Sleep(); 225 | pinMode(LED,INPUT); 226 | pinMode(4,INPUT); 227 | pinMode(5,INPUT); 228 | pinMode(14,INPUT); 229 | pinMode(15,INPUT); 230 | pinMode(16,INPUT); 231 | pinMode(17,INPUT); 232 | pinMode(18,INPUT); 233 | pinMode(19,INPUT); 234 | pinMode(26,INPUT); 235 | pinMode(27,INPUT); 236 | digitalWrite(Vext,HIGH); 237 | delay(2); 238 | esp_deep_sleep_start(); 239 | } 240 | break; 241 | default: 242 | break; 243 | } 244 | } 245 | 246 | void OnTxDone( void ) 247 | { 248 | Serial.print("TX done......"); 249 | displayInof(); 250 | state=STATUS_RX; 251 | } 252 | 253 | void OnTxTimeout( void ) 254 | { 255 | Radio.Sleep( ); 256 | Serial.print("TX Timeout......"); 257 | state=STATUS_TX; 258 | } 259 | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) 260 | { 261 | digitalWrite(LED,HIGH); 262 | Rssi=rssi; 263 | rxSize=size; 264 | memcpy(rxpacket, payload, size ); 265 | rxpacket[size]='\0'; 266 | Radio.Sleep( ); 267 | 268 | Serial.printf("\r\nreceived packet \"%s\" with Rssi %d , length %d\r\n",rxpacket,Rssi,rxSize); 269 | Serial.println("wait to send next packet"); 270 | displayInof(); 271 | state=STATUS_TX; 272 | } 273 | 274 | void displayInof() 275 | { 276 | Display.clear(); 277 | Display.drawString(0, 0, String(txNumber,DEC) + " sent done"); 278 | Display.drawString(0, 9, "Received " + String(rxSize,DEC)); 279 | Display.drawString(0, 16, rxpacket); 280 | Display.drawString(0, 24, "With rssi " + String(Rssi,DEC)); 281 | Display.display(); 282 | } 283 | -------------------------------------------------------------------------------- /examples/FactoryTest/Factory_Test_Wireless_Stick/images.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGES_H 2 | #define IMAGES_H 3 | 4 | #define logo_width 128 5 | #define logo_height 53 6 | const static char logo_bits[] = { 7 | 8 | 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xF0, 0x03, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0xC0, 0x07, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF0, 0x1F, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0xE0, 0x1F, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0xE0, 0x3F, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0xF8, 0x3F, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0xE0, 0x1F, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0xFC, 0x1F, 23 | 0x80, 0xFF, 0x8F, 0x7F, 0xC0, 0xFF, 0x7F, 0xC0, 0xFF, 0x03, 0xC0, 0x3F, 24 | 0xF0, 0x1F, 0xFC, 0x1F, 0xE0, 0xFF, 0x87, 0x3F, 0xC0, 0xFF, 0x7F, 0xF0, 25 | 0xFF, 0x01, 0xF8, 0xFF, 0xF0, 0x0F, 0xFC, 0x1F, 0xE0, 0xFF, 0x87, 0x3F, 26 | 0xE0, 0xFF, 0x7F, 0xF8, 0xFF, 0x01, 0xFE, 0xFF, 0xF8, 0x0F, 0xFE, 0x0F, 27 | 0xF0, 0xFF, 0x87, 0x3F, 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0x01, 0xFF, 0xFF, 28 | 0xF8, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xC7, 0x3F, 0xE0, 0xFF, 0x3F, 0xFC, 29 | 0xFF, 0x81, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xC3, 0x1F, 30 | 0xE0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0x0F, 31 | 0xF8, 0xFF, 0xC3, 0x1F, 0xE0, 0xFF, 0x3F, 0xFC, 0xFF, 0xE0, 0xFF, 0x7F, 32 | 0xFC, 0xFF, 0xFF, 0x07, 0xF8, 0x03, 0xC0, 0x1F, 0x00, 0xFE, 0x01, 0xFE, 33 | 0x00, 0xF0, 0x3F, 0x70, 0xFC, 0xFF, 0xFF, 0x07, 0xF8, 0x03, 0xE0, 0x0F, 34 | 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xF0, 0x1F, 0x60, 0xFC, 0xFF, 0xFF, 0x07, 35 | 0xF8, 0x03, 0xE0, 0x0F, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xF0, 0x07, 0x20, 36 | 0xFE, 0xFF, 0xFF, 0x07, 0xFC, 0xFF, 0xE1, 0x0F, 0x00, 0xFF, 0x00, 0xFF, 37 | 0x7F, 0xF8, 0x07, 0x00, 0xFE, 0x83, 0xFF, 0x03, 0xFC, 0xFF, 0xF1, 0x0F, 38 | 0x00, 0x7F, 0x00, 0xFF, 0x7F, 0xF8, 0x03, 0x00, 0xFE, 0x83, 0xFF, 0x03, 39 | 0xFC, 0xFF, 0xF0, 0x07, 0x00, 0x7F, 0x00, 0xFF, 0x7F, 0xFC, 0x03, 0x00, 40 | 0xFE, 0x81, 0xFF, 0x03, 0xFC, 0xFF, 0xF0, 0x07, 0x00, 0x7F, 0x00, 0xFF, 41 | 0x3F, 0xFC, 0x03, 0x00, 0xFF, 0xC1, 0xFF, 0x01, 0xFE, 0xFF, 0xF0, 0x07, 42 | 0x80, 0x3F, 0x80, 0xFF, 0x3F, 0xFC, 0x03, 0x00, 0xFF, 0xC1, 0xFF, 0x01, 43 | 0xFE, 0xFF, 0xF8, 0x07, 0x80, 0x3F, 0x80, 0xFF, 0x3F, 0xFC, 0x03, 0x10, 44 | 0xFF, 0xC1, 0xFF, 0x01, 0xFE, 0x00, 0xF8, 0x03, 0x80, 0x3F, 0x80, 0x3F, 45 | 0x00, 0xFC, 0x03, 0x0C, 0xFF, 0xC0, 0xFF, 0x01, 0xFF, 0x00, 0xF8, 0x03, 46 | 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0xFC, 0x07, 0x0E, 0xFF, 0xE0, 0xFF, 0x00, 47 | 0x7F, 0x00, 0xF8, 0x03, 0xC0, 0x1F, 0xC0, 0x3F, 0x00, 0xFC, 0xFF, 0x0F, 48 | 0xFF, 0xE0, 0xFF, 0x00, 0xFF, 0x7F, 0xFC, 0xFF, 0xC1, 0x1F, 0xC0, 0xFF, 49 | 0x1F, 0xFC, 0xFF, 0x0F, 0x7F, 0xE0, 0xFF, 0x00, 0xFF, 0x3F, 0xFC, 0xFF, 50 | 0xC1, 0x1F, 0xC0, 0xFF, 0x0F, 0xF8, 0xFF, 0x07, 0x7E, 0xE0, 0xFF, 0x80, 51 | 0xFF, 0x3F, 0xFC, 0xFF, 0xE0, 0x1F, 0xC0, 0xFF, 0x0F, 0xF8, 0xFF, 0x07, 52 | 0x7C, 0xF0, 0x7F, 0x80, 0xFF, 0x3F, 0xFE, 0xFF, 0xE0, 0x0F, 0xE0, 0xFF, 53 | 0x0F, 0xF0, 0xFF, 0x07, 0xF8, 0xF0, 0x7F, 0x80, 0xFF, 0x1F, 0xFE, 0xFF, 54 | 0xE0, 0x0F, 0xE0, 0xFF, 0x0F, 0xE0, 0xFF, 0x07, 0xE0, 0xF0, 0x7F, 0x80, 55 | 0xFF, 0x1F, 0xFE, 0xFF, 0xE0, 0x0F, 0xE0, 0xFF, 0x07, 0x80, 0xFF, 0x03, 56 | 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x3C, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x8F, 0xF7, 0xFF, 0x7C, 62 | 0xBC, 0xC7, 0xF3, 0xFF, 0xFC, 0xBC, 0x07, 0x00, 0x00, 0xFC, 0x1F, 0x00, 63 | 0x8F, 0x73, 0xFF, 0xFE, 0xBE, 0xC7, 0xFB, 0xFF, 0xFE, 0xBD, 0x03, 0x00, 64 | 0x00, 0xFC, 0x1F, 0x80, 0x8F, 0x73, 0xFF, 0xEF, 0xFE, 0xE7, 0xFB, 0x77, 65 | 0xEF, 0xFD, 0x03, 0x00, 0x00, 0xFC, 0x1F, 0x80, 0xDF, 0x7B, 0x9C, 0xE7, 66 | 0xFE, 0xF7, 0xE3, 0x71, 0xE7, 0xFD, 0x03, 0x00, 0x00, 0xFC, 0x0F, 0xC0, 67 | 0xDF, 0x79, 0x9E, 0xE3, 0xFE, 0xF3, 0xE3, 0x78, 0xE7, 0xFF, 0x03, 0x00, 68 | 0x00, 0xFC, 0x0F, 0xE0, 0xDF, 0x39, 0x8E, 0xF3, 0xFF, 0xFB, 0xE7, 0xF8, 69 | 0xE7, 0xFE, 0x01, 0x00, 0x00, 0xFC, 0x0F, 0xE0, 0xDF, 0x3F, 0x8E, 0x7F, 70 | 0xFF, 0xFF, 0xE7, 0x38, 0x7F, 0xEE, 0x01, 0x00, 0x00, 0xF8, 0x0F, 0x70, 71 | 0xDC, 0x1F, 0x0E, 0x3F, 0xFF, 0x9D, 0xF7, 0x38, 0x3F, 0xEF, 0x01, 0x00, 72 | 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 73 | 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; 79 | 80 | const char activeSymbol[] PROGMEM = { 81 | B00000000, 82 | B00000000, 83 | B00011000, 84 | B00100100, 85 | B01000010, 86 | B01000010, 87 | B00100100, 88 | B00011000 89 | }; 90 | 91 | const char inactiveSymbol[] PROGMEM = { 92 | B00000000, 93 | B00000000, 94 | B00000000, 95 | B00000000, 96 | B00011000, 97 | B00011000, 98 | B00000000, 99 | B00000000 100 | }; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /examples/FactoryTest/Factory_Test_Wireless_Stick_Lite/Factory_Test_Wireless_Stick_Lite.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Arduino.h" 3 | #include "WiFi.h" 4 | #include "images.h" 5 | 6 | #define USER_KEY 0 7 | #define YOUR_SSID "your ssid" 8 | #define YOUR_PASSWORD "your password" 9 | 10 | #define RF_FREQUENCY 868000000 // Hz 11 | 12 | #define TX_OUTPUT_POWER 14 // dBm 13 | 14 | #define LORA_BANDWIDTH 0 // [0: 125 kHz, 15 | // 1: 250 kHz, 16 | // 2: 500 kHz, 17 | // 3: Reserved] 18 | #define LORA_SPREADING_FACTOR 7 // [SF7..SF12] 19 | #define LORA_CODINGRATE 1 // [1: 4/5, 20 | // 2: 4/6, 21 | // 3: 4/7, 22 | // 4: 4/8] 23 | #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx 24 | #define LORA_SYMBOL_TIMEOUT 0 // Symbols 25 | #define LORA_FIX_LENGTH_PAYLOAD_ON false 26 | #define LORA_IQ_INVERSION_ON false 27 | 28 | 29 | #define RX_TIMEOUT_VALUE 1000 30 | #define BUFFER_SIZE 30 // Define the payload size here 31 | 32 | char txpacket[BUFFER_SIZE]; 33 | char rxpacket[BUFFER_SIZE]; 34 | 35 | static RadioEvents_t RadioEvents; 36 | void OnTxDone( void ); 37 | void OnTxTimeout( void ); 38 | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); 39 | 40 | typedef enum 41 | { 42 | STATUS_LOWPOWER, 43 | STATUS_RX, 44 | STATUS_TX 45 | }States_t; 46 | 47 | 48 | int16_t txNumber; 49 | States_t state; 50 | bool sleepMode = false; 51 | int16_t Rssi,rxSize; 52 | 53 | uint32_t license[4] = {0xD5397DF0, 0x8573F814, 0x7A38C73D, 0x48E68607}; 54 | 55 | void WIFISetUp(void) 56 | { 57 | // Set WiFi to station mode and disconnect from an AP if it was previously connected 58 | WiFi.disconnect(true); 59 | delay(100); 60 | WiFi.mode(WIFI_STA); 61 | WiFi.setAutoConnect(true); 62 | WiFi.begin(YOUR_SSID,YOUR_PASSWORD);//fill in "Your WiFi SSID","Your Password" 63 | delay(100); 64 | 65 | byte count = 0; 66 | while(WiFi.status() != WL_CONNECTED && count < 10) 67 | { 68 | count ++; 69 | Serial.print("."); 70 | delay(500); 71 | } 72 | 73 | if(WiFi.status() == WL_CONNECTED) 74 | { 75 | Serial.println("\r\nConnecting...OK."); 76 | } 77 | else 78 | { 79 | Serial.println("Connecting...Failed"); 80 | } 81 | Serial.println("WIFI Setup done"); 82 | } 83 | 84 | void WIFIScan(unsigned int value) 85 | { 86 | unsigned int i; 87 | WiFi.mode(WIFI_STA); 88 | 89 | for(i=0;i>32));//print High 2 bytes 156 | Serial.printf("%08X\n",(uint32_t)chipid);//print Low 4bytes. 157 | delay(100); 158 | 159 | SPI.begin(SCK,MISO,MOSI,SS); 160 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 161 | 162 | WIFISetUp(); 163 | WiFi.disconnect(); //重新初始化WIFI 164 | WiFi.mode(WIFI_STA); 165 | delay(100); 166 | 167 | WIFIScan(1); 168 | 169 | txNumber=0; 170 | Rssi=0; 171 | 172 | RadioEvents.TxDone = OnTxDone; 173 | RadioEvents.TxTimeout = OnTxTimeout; 174 | RadioEvents.RxDone = OnRxDone; 175 | 176 | Radio.Init( &RadioEvents ); 177 | Radio.SetChannel( RF_FREQUENCY ); 178 | Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, 179 | LORA_SPREADING_FACTOR, LORA_CODINGRATE, 180 | LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, 181 | true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); 182 | 183 | Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, 184 | LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, 185 | LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 186 | 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); 187 | state=STATUS_TX; 188 | pinMode(USER_KEY,INPUT_PULLUP); 189 | attachInterrupt(USER_KEY,interrupt,FALLING); 190 | } 191 | 192 | 193 | void loop() 194 | { 195 | switch(state) 196 | { 197 | case STATUS_TX: 198 | delay(1000); 199 | txNumber++; 200 | sprintf(txpacket,"%s","hello"); 201 | sprintf(txpacket+strlen(txpacket),"%d",txNumber); 202 | sprintf(txpacket+strlen(txpacket),"%s"," Rssi : "); 203 | sprintf(txpacket+strlen(txpacket),"%d",Rssi); 204 | 205 | Serial.printf("\r\nsending packet \"%s\" , length %d\r\n",txpacket, strlen(txpacket)); 206 | 207 | Radio.Send( (uint8_t *)txpacket, strlen(txpacket) ); 208 | state=STATUS_LOWPOWER; 209 | break; 210 | case STATUS_RX: 211 | Serial.println("into RX mode"); 212 | Radio.Rx( 0 ); 213 | state=STATUS_LOWPOWER; 214 | break; 215 | case STATUS_LOWPOWER: 216 | LoRaWAN.sleep(CLASS_C,0); 217 | if(deepsleepflag) 218 | { 219 | delay(200); 220 | LoRaWAN.sleep(CLASS_C,0); 221 | Serial.println("lowpower"); 222 | Radio.Sleep(); 223 | pinMode(LED,INPUT); 224 | pinMode(4,INPUT); 225 | pinMode(5,INPUT); 226 | pinMode(14,INPUT); 227 | pinMode(15,INPUT); 228 | pinMode(16,INPUT); 229 | pinMode(17,INPUT); 230 | pinMode(18,INPUT); 231 | pinMode(19,INPUT); 232 | pinMode(26,INPUT); 233 | pinMode(27,INPUT); 234 | digitalWrite(Vext,HIGH); 235 | delay(2); 236 | esp_deep_sleep_start(); 237 | } 238 | break; 239 | default: 240 | break; 241 | } 242 | } 243 | 244 | void OnTxDone( void ) 245 | { 246 | Serial.print("TX done......"); 247 | state=STATUS_RX; 248 | } 249 | 250 | void OnTxTimeout( void ) 251 | { 252 | Radio.Sleep( ); 253 | Serial.print("TX Timeout......"); 254 | state=STATUS_TX; 255 | } 256 | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) 257 | { 258 | digitalWrite(LED,HIGH); 259 | Rssi=rssi; 260 | rxSize=size; 261 | memcpy(rxpacket, payload, size ); 262 | rxpacket[size]='\0'; 263 | Radio.Sleep( ); 264 | 265 | Serial.printf("\r\nreceived packet \"%s\" with Rssi %d , length %d\r\n",rxpacket,Rssi,rxSize); 266 | Serial.println("wait to send next packet"); 267 | state=STATUS_TX; 268 | } 269 | -------------------------------------------------------------------------------- /examples/FactoryTest/Factory_Test_Wireless_Stick_Lite/images.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGES_H 2 | #define IMAGES_H 3 | 4 | #define logo_width 128 5 | #define logo_height 53 6 | const static char logo_bits[] = { 7 | 8 | 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xF0, 0x03, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0xC0, 0x07, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0F, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1F, 0xF0, 0x1F, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0xE0, 0x1F, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0xE0, 0x3F, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x1F, 0xF8, 0x3F, 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0xE0, 0x1F, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x1F, 0xFC, 0x1F, 23 | 0x80, 0xFF, 0x8F, 0x7F, 0xC0, 0xFF, 0x7F, 0xC0, 0xFF, 0x03, 0xC0, 0x3F, 24 | 0xF0, 0x1F, 0xFC, 0x1F, 0xE0, 0xFF, 0x87, 0x3F, 0xC0, 0xFF, 0x7F, 0xF0, 25 | 0xFF, 0x01, 0xF8, 0xFF, 0xF0, 0x0F, 0xFC, 0x1F, 0xE0, 0xFF, 0x87, 0x3F, 26 | 0xE0, 0xFF, 0x7F, 0xF8, 0xFF, 0x01, 0xFE, 0xFF, 0xF8, 0x0F, 0xFE, 0x0F, 27 | 0xF0, 0xFF, 0x87, 0x3F, 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0x01, 0xFF, 0xFF, 28 | 0xF8, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xC7, 0x3F, 0xE0, 0xFF, 0x3F, 0xFC, 29 | 0xFF, 0x81, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xF0, 0xFF, 0xC3, 0x1F, 30 | 0xE0, 0xFF, 0x3F, 0xFC, 0xFF, 0xC0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0x0F, 31 | 0xF8, 0xFF, 0xC3, 0x1F, 0xE0, 0xFF, 0x3F, 0xFC, 0xFF, 0xE0, 0xFF, 0x7F, 32 | 0xFC, 0xFF, 0xFF, 0x07, 0xF8, 0x03, 0xC0, 0x1F, 0x00, 0xFE, 0x01, 0xFE, 33 | 0x00, 0xF0, 0x3F, 0x70, 0xFC, 0xFF, 0xFF, 0x07, 0xF8, 0x03, 0xE0, 0x0F, 34 | 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xF0, 0x1F, 0x60, 0xFC, 0xFF, 0xFF, 0x07, 35 | 0xF8, 0x03, 0xE0, 0x0F, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0xF0, 0x07, 0x20, 36 | 0xFE, 0xFF, 0xFF, 0x07, 0xFC, 0xFF, 0xE1, 0x0F, 0x00, 0xFF, 0x00, 0xFF, 37 | 0x7F, 0xF8, 0x07, 0x00, 0xFE, 0x83, 0xFF, 0x03, 0xFC, 0xFF, 0xF1, 0x0F, 38 | 0x00, 0x7F, 0x00, 0xFF, 0x7F, 0xF8, 0x03, 0x00, 0xFE, 0x83, 0xFF, 0x03, 39 | 0xFC, 0xFF, 0xF0, 0x07, 0x00, 0x7F, 0x00, 0xFF, 0x7F, 0xFC, 0x03, 0x00, 40 | 0xFE, 0x81, 0xFF, 0x03, 0xFC, 0xFF, 0xF0, 0x07, 0x00, 0x7F, 0x00, 0xFF, 41 | 0x3F, 0xFC, 0x03, 0x00, 0xFF, 0xC1, 0xFF, 0x01, 0xFE, 0xFF, 0xF0, 0x07, 42 | 0x80, 0x3F, 0x80, 0xFF, 0x3F, 0xFC, 0x03, 0x00, 0xFF, 0xC1, 0xFF, 0x01, 43 | 0xFE, 0xFF, 0xF8, 0x07, 0x80, 0x3F, 0x80, 0xFF, 0x3F, 0xFC, 0x03, 0x10, 44 | 0xFF, 0xC1, 0xFF, 0x01, 0xFE, 0x00, 0xF8, 0x03, 0x80, 0x3F, 0x80, 0x3F, 45 | 0x00, 0xFC, 0x03, 0x0C, 0xFF, 0xC0, 0xFF, 0x01, 0xFF, 0x00, 0xF8, 0x03, 46 | 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0xFC, 0x07, 0x0E, 0xFF, 0xE0, 0xFF, 0x00, 47 | 0x7F, 0x00, 0xF8, 0x03, 0xC0, 0x1F, 0xC0, 0x3F, 0x00, 0xFC, 0xFF, 0x0F, 48 | 0xFF, 0xE0, 0xFF, 0x00, 0xFF, 0x7F, 0xFC, 0xFF, 0xC1, 0x1F, 0xC0, 0xFF, 49 | 0x1F, 0xFC, 0xFF, 0x0F, 0x7F, 0xE0, 0xFF, 0x00, 0xFF, 0x3F, 0xFC, 0xFF, 50 | 0xC1, 0x1F, 0xC0, 0xFF, 0x0F, 0xF8, 0xFF, 0x07, 0x7E, 0xE0, 0xFF, 0x80, 51 | 0xFF, 0x3F, 0xFC, 0xFF, 0xE0, 0x1F, 0xC0, 0xFF, 0x0F, 0xF8, 0xFF, 0x07, 52 | 0x7C, 0xF0, 0x7F, 0x80, 0xFF, 0x3F, 0xFE, 0xFF, 0xE0, 0x0F, 0xE0, 0xFF, 53 | 0x0F, 0xF0, 0xFF, 0x07, 0xF8, 0xF0, 0x7F, 0x80, 0xFF, 0x1F, 0xFE, 0xFF, 54 | 0xE0, 0x0F, 0xE0, 0xFF, 0x0F, 0xE0, 0xFF, 0x07, 0xE0, 0xF0, 0x7F, 0x80, 55 | 0xFF, 0x1F, 0xFE, 0xFF, 0xE0, 0x0F, 0xE0, 0xFF, 0x07, 0x80, 0xFF, 0x03, 56 | 0x00, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x3C, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3F, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 | 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x8F, 0xF7, 0xFF, 0x7C, 62 | 0xBC, 0xC7, 0xF3, 0xFF, 0xFC, 0xBC, 0x07, 0x00, 0x00, 0xFC, 0x1F, 0x00, 63 | 0x8F, 0x73, 0xFF, 0xFE, 0xBE, 0xC7, 0xFB, 0xFF, 0xFE, 0xBD, 0x03, 0x00, 64 | 0x00, 0xFC, 0x1F, 0x80, 0x8F, 0x73, 0xFF, 0xEF, 0xFE, 0xE7, 0xFB, 0x77, 65 | 0xEF, 0xFD, 0x03, 0x00, 0x00, 0xFC, 0x1F, 0x80, 0xDF, 0x7B, 0x9C, 0xE7, 66 | 0xFE, 0xF7, 0xE3, 0x71, 0xE7, 0xFD, 0x03, 0x00, 0x00, 0xFC, 0x0F, 0xC0, 67 | 0xDF, 0x79, 0x9E, 0xE3, 0xFE, 0xF3, 0xE3, 0x78, 0xE7, 0xFF, 0x03, 0x00, 68 | 0x00, 0xFC, 0x0F, 0xE0, 0xDF, 0x39, 0x8E, 0xF3, 0xFF, 0xFB, 0xE7, 0xF8, 69 | 0xE7, 0xFE, 0x01, 0x00, 0x00, 0xFC, 0x0F, 0xE0, 0xDF, 0x3F, 0x8E, 0x7F, 70 | 0xFF, 0xFF, 0xE7, 0x38, 0x7F, 0xEE, 0x01, 0x00, 0x00, 0xF8, 0x0F, 0x70, 71 | 0xDC, 0x1F, 0x0E, 0x3F, 0xFF, 0x9D, 0xF7, 0x38, 0x3F, 0xEF, 0x01, 0x00, 72 | 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 73 | 0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 | 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; 79 | 80 | const char activeSymbol[] PROGMEM = { 81 | B00000000, 82 | B00000000, 83 | B00011000, 84 | B00100100, 85 | B01000010, 86 | B01000010, 87 | B00100100, 88 | B00011000 89 | }; 90 | 91 | const char inactiveSymbol[] PROGMEM = { 92 | B00000000, 93 | B00000000, 94 | B00000000, 95 | B00000000, 96 | B00011000, 97 | B00011000, 98 | B00000000, 99 | B00000000 100 | }; 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /examples/OTAA/OTAA.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A 3 | * 4 | * Function summary: 5 | * 6 | * - use internal RTC(150KHz); 7 | * 8 | * - Include stop mode and deep sleep mode; 9 | * 10 | * - 15S data send cycle; 11 | * 12 | * - Informations output via serial(115200); 13 | * 14 | * - Only ESP32 + LoRa series boards can use this library, need a license 15 | * to make the code run(check you license here: http://www.heltec.cn/search/); 16 | * 17 | * You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h" 18 | * 19 | * HelTec AutoMation, Chengdu, China. 20 | * 成都惠利特自动化科技有限公司 21 | * https://heltec.org 22 | * support@heltec.cn 23 | * 24 | *this project also release in GitHub: 25 | *https://github.com/HelTecAutomation/ESP32_LoRaWAN 26 | */ 27 | 28 | #include 29 | #include "Arduino.h" 30 | 31 | /*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */ 32 | uint32_t license[4] = {0xD5397DF0, 0x8573F814, 0x7A38C73D, 0x48E68607}; 33 | 34 | /* OTAA para*/ 35 | uint8_t DevEui[] = { 0x22, 0x32, 0x33, 0x00, 0x00, 0x88, 0x88, 0x02 }; 36 | uint8_t AppEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 37 | uint8_t AppKey[] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01 }; 38 | 39 | /* ABP para*/ 40 | uint8_t NwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 }; 41 | uint8_t AppSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef,0x67 }; 42 | uint32_t DevAddr = ( uint32_t )0x007e6ae1; 43 | 44 | /*LoraWan channelsmask, default channels 0-7*/ 45 | uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; 46 | 47 | /*LoraWan Class, Class A and Class C are supported*/ 48 | DeviceClass_t loraWanClass = CLASS_A; 49 | 50 | /*the application data transmission duty cycle. value in [ms].*/ 51 | uint32_t appTxDutyCycle = 15000; 52 | 53 | /*OTAA or ABP*/ 54 | bool overTheAirActivation = true; 55 | 56 | /*ADR enable*/ 57 | bool loraWanAdr = true; 58 | 59 | /* Indicates if the node is sending confirmed or unconfirmed messages */ 60 | bool isTxConfirmed = true; 61 | 62 | /* Application port */ 63 | uint8_t appPort = 2; 64 | 65 | /*! 66 | * Number of trials to transmit the frame, if the LoRaMAC layer did not 67 | * receive an acknowledgment. The MAC performs a datarate adaptation, 68 | * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according 69 | * to the following table: 70 | * 71 | * Transmission nb | Data Rate 72 | * ----------------|----------- 73 | * 1 (first) | DR 74 | * 2 | DR 75 | * 3 | max(DR-1,0) 76 | * 4 | max(DR-1,0) 77 | * 5 | max(DR-2,0) 78 | * 6 | max(DR-2,0) 79 | * 7 | max(DR-3,0) 80 | * 8 | max(DR-3,0) 81 | * 82 | * Note, that if NbTrials is set to 1 or 2, the MAC will not decrease 83 | * the datarate, in case the LoRaMAC layer did not receive an acknowledgment 84 | */ 85 | uint8_t confirmedNbTrials = 8; 86 | 87 | /*LoraWan debug level, select in arduino IDE tools. 88 | * None : print basic info. 89 | * Freq : print Tx and Rx freq, DR info. 90 | * Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info. 91 | * Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt and MCU deepsleep info. 92 | */ 93 | uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; 94 | 95 | /*LoraWan region, select in arduino IDE tools*/ 96 | LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; 97 | 98 | static void prepareTxFrame( uint8_t port ) 99 | { 100 | appDataSize = 4;//AppDataSize max value is 64 ( src/Commissioning.h -> 128 ) 101 | appData[0] = 0x00; 102 | appData[1] = 0x01; 103 | appData[2] = 0x02; 104 | appData[3] = 0x03; 105 | } 106 | 107 | // Add your initialization code here 108 | void setup() 109 | { 110 | Serial.begin(115200); 111 | while (!Serial); 112 | SPI.begin(SCK,MISO,MOSI,SS); 113 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 114 | deviceState = DEVICE_STATE_INIT; 115 | } 116 | 117 | // The loop function is called in an endless loop 118 | void loop() 119 | { 120 | switch( deviceState ) 121 | { 122 | case DEVICE_STATE_INIT: 123 | { 124 | #if(LORAWAN_DEVEUI_AUTO) 125 | LoRaWAN.generateDeveuiByChipID(); 126 | #endif 127 | LoRaWAN.init(loraWanClass,loraWanRegion); 128 | break; 129 | } 130 | case DEVICE_STATE_JOIN: 131 | { 132 | LoRaWAN.join(); 133 | break; 134 | } 135 | case DEVICE_STATE_SEND: 136 | { 137 | prepareTxFrame( appPort ); 138 | LoRaWAN.send(loraWanClass); 139 | deviceState = DEVICE_STATE_CYCLE; 140 | break; 141 | } 142 | case DEVICE_STATE_CYCLE: 143 | { 144 | // Schedule next packet transmission 145 | txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 146 | LoRaWAN.cycle(txDutyCycleTime); 147 | deviceState = DEVICE_STATE_SLEEP; 148 | break; 149 | } 150 | case DEVICE_STATE_SLEEP: 151 | { 152 | LoRaWAN.sleep(loraWanClass,debugLevel); 153 | break; 154 | } 155 | default: 156 | { 157 | deviceState = DEVICE_STATE_INIT; 158 | break; 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /examples/OTAA_Battery_power/OTAA_Battery_power.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A 3 | * 4 | * Function summary: 5 | * 6 | * - use internal RTC(150KHz); 7 | * 8 | * - Forward the data measured by the 12-bit ADC to the server. 9 | * 10 | * - Include stop mode and deep sleep mode; 11 | * 12 | * - 15S data send cycle; 13 | * 14 | * - Informations output via serial(115200); 15 | * 16 | * - Only ESP32 + LoRa series boards can use this library, need a license 17 | * to make the code run(check you license here: http://www.heltec.cn/search/); 18 | * 19 | * You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h" 20 | * 21 | * HelTec AutoMation, Chengdu, China. 22 | * 成都惠利特自动化科技有限公司 23 | * https://heltec.org 24 | * support@heltec.cn 25 | * 26 | *this project also release in GitHub: 27 | *https://github.com/HelTecAutomation/ESP32_LoRaWAN 28 | */ 29 | 30 | #include 31 | #include "Arduino.h" 32 | 33 | /*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */ 34 | uint32_t license[4] = {0x4915A653,0xC69E42EE,0x0D9EA6D4,0xB5201468}; 35 | 36 | /* OTAA para*/ 37 | uint8_t DevEui[] = { 0x22, 0x32, 0x33, 0x00, 0x00, 0x88, 0x88, 0x02 }; 38 | uint8_t AppEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 39 | uint8_t AppKey[] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01 }; 40 | 41 | /* ABP para*/ 42 | uint8_t NwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 }; 43 | uint8_t AppSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef,0x67 }; 44 | uint32_t DevAddr = ( uint32_t )0x007e6ae1; 45 | 46 | /*LoraWan channelsmask, default channels 0-7*/ 47 | uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; 48 | 49 | /*LoraWan Class, Class A and Class C are supported*/ 50 | DeviceClass_t loraWanClass = CLASS_A; 51 | 52 | /*the application data transmission duty cycle. value in [ms].*/ 53 | uint32_t appTxDutyCycle = 15000; 54 | 55 | /*OTAA or ABP*/ 56 | bool overTheAirActivation = true; 57 | 58 | /*ADR enable*/ 59 | bool loraWanAdr = true; 60 | 61 | /* Indicates if the node is sending confirmed or unconfirmed messages */ 62 | bool isTxConfirmed = true; 63 | 64 | /* Application port */ 65 | uint8_t appPort = 2; 66 | 67 | /*! 68 | * Number of trials to transmit the frame, if the LoRaMAC layer did not 69 | * receive an acknowledgment. The MAC performs a datarate adaptation, 70 | * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according 71 | * to the following table: 72 | * 73 | * Transmission nb | Data Rate 74 | * ----------------|----------- 75 | * 1 (first) | DR 76 | * 2 | DR 77 | * 3 | max(DR-1,0) 78 | * 4 | max(DR-1,0) 79 | * 5 | max(DR-2,0) 80 | * 6 | max(DR-2,0) 81 | * 7 | max(DR-3,0) 82 | * 8 | max(DR-3,0) 83 | * 84 | * Note, that if NbTrials is set to 1 or 2, the MAC will not decrease 85 | * the datarate, in case the LoRaMAC layer did not receive an acknowledgment 86 | */ 87 | uint8_t confirmedNbTrials = 8; 88 | 89 | /*LoraWan debug level, select in arduino IDE tools. 90 | * None : print basic info. 91 | * Freq : print Tx and Rx freq, DR info. 92 | * Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info. 93 | * Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt and MCU deepsleep info. 94 | */ 95 | uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; 96 | 97 | /*LoraWan region, select in arduino IDE tools*/ 98 | LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; 99 | 100 | static void ADC_Process(uint16_t val){ 101 | appDataSize = 4 ; 102 | int TH = (int)(val / 1000); 103 | appData[3] = (char)(TH) ; 104 | 105 | int HU = (int)((val - TH*1000) / 100); 106 | appData[2] = (char)(HU) ; 107 | 108 | int Ten = (int)((val - TH * 1000 - HU * 100) / 10); 109 | appData[1] = (char)(Ten) ; 110 | 111 | int Sin = (val % 10); 112 | appData[0] = (char)(Sin) ; 113 | } 114 | #define Vext 21 115 | // Add your initialization code here 116 | void setup() 117 | { 118 | Serial.begin(115200); 119 | while (!Serial); 120 | SPI.begin(SCK,MISO,MOSI,SS); 121 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 122 | 123 | adcAttachPin(37); 124 | analogSetClockDiv(255); // 1338mS 125 | pinMode(Vext, OUTPUT); 126 | deviceState = DEVICE_STATE_INIT; 127 | } 128 | 129 | // The loop function is called in an endless loop 130 | void loop() 131 | { 132 | switch( deviceState ) 133 | { 134 | case DEVICE_STATE_INIT: 135 | { 136 | #if(LORAWAN_DEVEUI_AUTO) 137 | LoRaWAN.generateDeveuiByChipID(); 138 | #endif 139 | LoRaWAN.init(loraWanClass,loraWanRegion); 140 | break; 141 | } 142 | case DEVICE_STATE_JOIN: 143 | { 144 | LoRaWAN.join(); 145 | break; 146 | } 147 | case DEVICE_STATE_SEND: 148 | { 149 | digitalWrite(Vext, LOW); 150 | delay(10); 151 | uint16_t ADC_voltage = analogRead(37); 152 | digitalWrite(Vext, HIGH); 153 | ADC_Process( ADC_voltage ); 154 | LoRaWAN.send(loraWanClass); 155 | deviceState = DEVICE_STATE_CYCLE; 156 | break; 157 | } 158 | case DEVICE_STATE_CYCLE: 159 | { 160 | // Schedule next packet transmission 161 | txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 162 | LoRaWAN.cycle(txDutyCycleTime); 163 | deviceState = DEVICE_STATE_SLEEP; 164 | break; 165 | } 166 | case DEVICE_STATE_SLEEP: 167 | { 168 | LoRaWAN.sleep(loraWanClass,debugLevel); 169 | break; 170 | } 171 | default: 172 | { 173 | deviceState = DEVICE_STATE_INIT; 174 | break; 175 | } 176 | } 177 | } -------------------------------------------------------------------------------- /examples/OTAA_LED/OTAA_LED.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A 3 | * 4 | * Function summary: 5 | * 6 | * - You can use port 4 to control the LED light. 7 | * 8 | * - If the issued value is 1(ASCII), the lamp will be lit. 9 | * 10 | * - The release value is 2(ASCII) and the light will be turned off. 11 | * 12 | * - use internal RTC(150KHz); 13 | * 14 | * - Include stop mode and deep sleep mode; 15 | * 16 | * - 15S data send cycle; 17 | * 18 | * - Informations output via serial(115200); 19 | * 20 | * - Only ESP32 + LoRa series boards can use this library, need a license 21 | * to make the code run(check you license here: http://www.heltec.cn/search/); 22 | * 23 | * You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h" 24 | * 25 | * HelTec AutoMation, Chengdu, China. 26 | * 成都惠利特自动化科技有限公司 27 | * https://heltec.org 28 | * support@heltec.cn 29 | * 30 | *this project also release in GitHub: 31 | *https://github.com/HelTecAutomation/ESP32_LoRaWAN 32 | */ 33 | 34 | #include 35 | #include "Arduino.h" 36 | 37 | /*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */ 38 | uint32_t license[4] = {0x4915A653,0xC69E42EE,0x0D9EA6D4,0xB5201468}; 39 | 40 | /* OTAA para*/ 41 | uint8_t DevEui[] = { 0x22, 0x32, 0x33, 0x00, 0x00, 0x88, 0x88, 0x02 }; 42 | uint8_t AppEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 43 | uint8_t AppKey[] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01 }; 44 | 45 | /* ABP para*/ 46 | uint8_t NwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 }; 47 | uint8_t AppSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef,0x67 }; 48 | uint32_t DevAddr = ( uint32_t )0x007e6ae1; 49 | 50 | /*LoraWan channelsmask, default channels 0-7*/ 51 | uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; 52 | 53 | /*LoraWan Class, Class A and Class C are supported*/ 54 | DeviceClass_t loraWanClass = CLASS_C; 55 | 56 | /*the application data transmission duty cycle. value in [ms].*/ 57 | uint32_t appTxDutyCycle = 15000; 58 | 59 | /*OTAA or ABP*/ 60 | bool overTheAirActivation = true; 61 | 62 | /*ADR enable*/ 63 | bool loraWanAdr = true; 64 | 65 | /* Indicates if the node is sending confirmed or unconfirmed messages */ 66 | bool isTxConfirmed = true; 67 | 68 | /* Application port */ 69 | uint8_t appPort = 2; 70 | 71 | /*! 72 | * Number of trials to transmit the frame, if the LoRaMAC layer did not 73 | * receive an acknowledgment. The MAC performs a datarate adaptation, 74 | * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according 75 | * to the following table: 76 | * 77 | * Transmission nb | Data Rate 78 | * ----------------|----------- 79 | * 1 (first) | DR 80 | * 2 | DR 81 | * 3 | max(DR-1,0) 82 | * 4 | max(DR-1,0) 83 | * 5 | max(DR-2,0) 84 | * 6 | max(DR-2,0) 85 | * 7 | max(DR-3,0) 86 | * 8 | max(DR-3,0) 87 | * 88 | * Note, that if NbTrials is set to 1 or 2, the MAC will not decrease 89 | * the datarate, in case the LoRaMAC layer did not receive an acknowledgment 90 | */ 91 | uint8_t confirmedNbTrials = 8; 92 | 93 | /*LoraWan debug level, select in arduino IDE tools. 94 | * None : print basic info. 95 | * Freq : print Tx and Rx freq, DR info. 96 | * Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info. 97 | * Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt and MCU deepsleep info. 98 | */ 99 | uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; 100 | 101 | /*LoraWan region, select in arduino IDE tools*/ 102 | LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; 103 | 104 | 105 | #define LEDPin 25 //LED light 106 | void app(uint8_t data) 107 | { 108 | // lora_printf("data:%d\r\n",data); 109 | switch(data) 110 | { 111 | case 49: 112 | { 113 | pinMode(LEDPin,OUTPUT); 114 | digitalWrite(LEDPin, HIGH); 115 | break; 116 | } 117 | case 50: 118 | { 119 | pinMode(LEDPin,OUTPUT); 120 | digitalWrite(LEDPin, LOW); 121 | break; 122 | } 123 | case 51: 124 | { 125 | break; 126 | } 127 | default: 128 | { 129 | break; 130 | } 131 | } 132 | } 133 | 134 | 135 | void downLinkDataHandle(McpsIndication_t *mcpsIndication) 136 | { 137 | lora_printf("+REV DATA:%s,RXSIZE %d,PORT %d\r\n",mcpsIndication->RxSlot?"RXWIN2":"RXWIN1",mcpsIndication->BufferSize,mcpsIndication->Port); 138 | lora_printf("+REV DATA:"); 139 | app(mcpsIndication->Buffer[0]); 140 | 141 | for(uint8_t i=0;iBufferSize;i++) 142 | { 143 | lora_printf("%02X",mcpsIndication->Buffer[i]); 144 | } 145 | lora_printf("\r\n"); 146 | } 147 | 148 | 149 | 150 | static void prepareTxFrame( uint8_t port ) 151 | { 152 | appDataSize = 4;//AppDataSize max value is 64 153 | appData[0] = 0x00; 154 | appData[1] = 0x01; 155 | appData[2] = 0x02; 156 | appData[3] = 0x03; 157 | } 158 | 159 | // Add your initialization code here 160 | void setup() 161 | { 162 | Serial.begin(115200); 163 | while (!Serial); 164 | SPI.begin(SCK,MISO,MOSI,SS); 165 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 166 | deviceState = DEVICE_STATE_INIT; 167 | } 168 | 169 | // The loop function is called in an endless loop 170 | void loop() 171 | { 172 | switch( deviceState ) 173 | { 174 | case DEVICE_STATE_INIT: 175 | { 176 | #if(LORAWAN_DEVEUI_AUTO) 177 | LoRaWAN.generateDeveuiByChipID(); 178 | #endif 179 | LoRaWAN.init(loraWanClass,loraWanRegion); 180 | break; 181 | } 182 | case DEVICE_STATE_JOIN: 183 | { 184 | LoRaWAN.join(); 185 | break; 186 | } 187 | case DEVICE_STATE_SEND: 188 | { 189 | prepareTxFrame( appPort ); 190 | LoRaWAN.send(loraWanClass); 191 | deviceState = DEVICE_STATE_CYCLE; 192 | break; 193 | } 194 | case DEVICE_STATE_CYCLE: 195 | { 196 | // Schedule next packet transmission 197 | txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 198 | LoRaWAN.cycle(txDutyCycleTime); 199 | deviceState = DEVICE_STATE_SLEEP; 200 | break; 201 | } 202 | case DEVICE_STATE_SLEEP: 203 | { 204 | LoRaWAN.sleep(loraWanClass,debugLevel); 205 | break; 206 | } 207 | default: 208 | { 209 | deviceState = DEVICE_STATE_INIT; 210 | break; 211 | } 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /examples/OTAA_OLED/OTAA_OLED.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A 3 | * 4 | * Function summary: 5 | * 6 | * - use internal RTC(150KHz); 7 | * 8 | * - Include stop mode and deep sleep mode; 9 | * 10 | * - 15S data send cycle; 11 | * 12 | * - Informations output via serial(115200); 13 | * 14 | * - Only ESP32 + LoRa series boards can use this library, need a license 15 | * to make the code run(check you license here: http://www.heltec.cn/search ); 16 | * 17 | * You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h" 18 | * 19 | * HelTec AutoMation, Chengdu, China. 20 | * 成都惠利特自动化科技有限公司 21 | * https://heltec.org 22 | * support@heltec.cn 23 | * 24 | *this project also release in GitHub: 25 | *https://github.com/HelTecAutomation/ESP32_LoRaWAN 26 | * 27 | * 28 | * To use this on Thethingsnetwork.org add the following Payload Formatter for this device 29 | /* 30 | function Decoder(bytes, port) { 31 | var humidity = (bytes[0]<<8) | bytes[1]; 32 | var temperature = (bytes[2]<<8) | bytes[3]; 33 | return { 34 | humidity: humidity/ 100, 35 | temperature: temperature/100 36 | } 37 | } 38 | */ 39 | */ 40 | 41 | #include 42 | #include "Arduino.h" 43 | 44 | /*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */ 45 | uint32_t license[4] = {0x00000000,0x00000000,0x00000000,0x00000000}; 46 | /* OTAA para*/ 47 | uint8_t DevEui[] = { 0x22, 0x32, 0x33, 0x00, 0x00, 0x88, 0x88, 0x02 }; 48 | uint8_t AppEui[] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0xB1, 0x8A }; 49 | uint8_t AppKey[] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01 }; 50 | 51 | /* ABP para*/ 52 | uint8_t NwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 }; 53 | uint8_t AppSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef,0x67 }; 54 | uint32_t DevAddr = ( uint32_t )0x007e6ae1; 55 | 56 | /*LoraWan channelsmask, default channels 0-7*/ 57 | uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; 58 | 59 | /*LoraWan Class, Class A and Class C are supported*/ 60 | DeviceClass_t loraWanClass = CLASS_A; 61 | 62 | /*the application data transmission duty cycle. value in [ms].*/ 63 | uint32_t appTxDutyCycle = 15000; 64 | 65 | /*OTAA or ABP*/ 66 | bool overTheAirActivation = true; 67 | 68 | /*ADR enable*/ 69 | bool loraWanAdr = true; 70 | 71 | /* Indicates if the node is sending confirmed or unconfirmed messages */ 72 | bool isTxConfirmed = true; 73 | 74 | /* Application port */ 75 | uint8_t appPort = 2; 76 | 77 | /*! 78 | * Number of trials to transmit the frame, if the LoRaMAC layer did not 79 | * receive an acknowledgment. The MAC performs a datarate adaptation, 80 | * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according 81 | * to the following table: 82 | * 83 | * Transmission nb | Data Rate 84 | * ----------------|----------- 85 | * 1 (first) | DR 86 | * 2 | DR 87 | * 3 | max(DR-1,0) 88 | * 4 | max(DR-1,0) 89 | * 5 | max(DR-2,0) 90 | * 6 | max(DR-2,0) 91 | * 7 | max(DR-3,0) 92 | * 8 | max(DR-3,0) 93 | * 94 | * Note, that if NbTrials is set to 1 or 2, the MAC will not decrease 95 | * the datarate, in case the LoRaMAC layer did not receive an acknowledgment 96 | */ 97 | uint8_t confirmedNbTrials = 8; 98 | 99 | /*LoraWan debug level, select in arduino IDE tools. 100 | * None : print basic info. 101 | * Freq : print Tx and Rx freq, DR info. 102 | * Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info. 103 | * Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt, MCU sleep and MCU wake info. 104 | */ 105 | uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; 106 | 107 | /*LoraWan region, select in arduino IDE tools*/ 108 | LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; 109 | 110 | 111 | static void prepareTxFrame( uint8_t port ) 112 | { 113 | appDataSize = 4;//AppDataSize max value is 64 114 | // Format the data to bytes 115 | appData[0] = 0x00; 116 | appData[1] = 0x01; 117 | appData[2] = 0x02; 118 | appData[3] = 0x03; 119 | 120 | } 121 | 122 | // Add your initialization code here 123 | void setup() 124 | { 125 | if(mcuStarted==0) 126 | { 127 | LoRaWAN.displayMcuInit(); 128 | } 129 | Serial.begin(115200); 130 | while (!Serial); 131 | SPI.begin(SCK,MISO,MOSI,SS); 132 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 133 | deviceState = DEVICE_STATE_INIT; 134 | } 135 | 136 | // The loop function is called in an endless loop 137 | void loop() 138 | { 139 | switch( deviceState ) 140 | { 141 | case DEVICE_STATE_INIT: 142 | { 143 | #if(LORAWAN_DEVEUI_AUTO) 144 | LoRaWAN.generateDeveuiByChipID(); 145 | #endif 146 | LoRaWAN.init(loraWanClass,loraWanRegion); 147 | break; 148 | } 149 | case DEVICE_STATE_JOIN: 150 | { 151 | LoRaWAN.displayJoining(); 152 | LoRaWAN.join(); 153 | break; 154 | } 155 | case DEVICE_STATE_SEND: 156 | { 157 | LoRaWAN.displaySending(); 158 | prepareTxFrame( appPort ); 159 | LoRaWAN.send(loraWanClass); 160 | deviceState = DEVICE_STATE_CYCLE; 161 | break; 162 | } 163 | case DEVICE_STATE_CYCLE: 164 | { 165 | // Schedule next packet transmission 166 | txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 167 | LoRaWAN.cycle(txDutyCycleTime); 168 | deviceState = DEVICE_STATE_SLEEP; 169 | break; 170 | } 171 | case DEVICE_STATE_SLEEP: 172 | { 173 | LoRaWAN.displayAck(); 174 | LoRaWAN.sleep(loraWanClass,debugLevel); 175 | break; 176 | } 177 | default: 178 | { 179 | deviceState = DEVICE_STATE_INIT; 180 | break; 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /examples/OTAA_OLED_Interrupt_CLASS_A/OTAA_OLED_Interrupt_CLASS_A.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A 3 | * 4 | * Function summary: 5 | * 6 | * - use internal RTC(150KHz); 7 | * 8 | * - Include stop mode and deep sleep mode; 9 | * 10 | * - 15S data send cycle; 11 | * 12 | * - Informations output via serial(115200); 13 | * 14 | * - Only ESP32 + LoRa series boards can use this library, need a license 15 | * to make the code run(check you license here: http://www.heltec.cn/search ); 16 | * 17 | * You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h" 18 | * 19 | * HelTec AutoMation, Chengdu, China. 20 | * 成都惠利特自动化科技有限公司 21 | * https://heltec.org 22 | * support@heltec.cn 23 | * 24 | *this project also release in GitHub: 25 | *https://github.com/HelTecAutomation/ESP32_LoRaWAN 26 | */ 27 | 28 | #include 29 | #include "Arduino.h" 30 | 31 | #define INT_PIN GPIO_NUM_0 32 | /*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */ 33 | uint32_t license[4] = {0x00000000,0x00000000,0x00000000,0x00000000}; 34 | /* OTAA para*/ 35 | uint8_t DevEui[] = { 0x22, 0x32, 0x33, 0x00, 0x00, 0x88, 0x88, 0x02 }; 36 | uint8_t AppEui[] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0xB1, 0x8A }; 37 | uint8_t AppKey[] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01 }; 38 | 39 | /* ABP para*/ 40 | uint8_t NwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 }; 41 | uint8_t AppSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef,0x67 }; 42 | uint32_t DevAddr = ( uint32_t )0x007e6ae1; 43 | 44 | /*LoraWan channelsmask, default channels 0-7*/ 45 | uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; 46 | 47 | /*LoraWan Class, Class A and Class C are supported*/ 48 | DeviceClass_t loraWanClass = CLASS_A; 49 | 50 | /*the application data transmission duty cycle. value in [ms].*/ 51 | uint32_t appTxDutyCycle = 3600*24*1000; 52 | 53 | /*OTAA or ABP*/ 54 | bool overTheAirActivation = true; 55 | 56 | /*ADR enable*/ 57 | bool loraWanAdr = true; 58 | 59 | /* Indicates if the node is sending confirmed or unconfirmed messages */ 60 | bool isTxConfirmed = true; 61 | 62 | /* Application port */ 63 | uint8_t appPort = 2; 64 | 65 | /*! 66 | * Number of trials to transmit the frame, if the LoRaMAC layer did not 67 | * receive an acknowledgment. The MAC performs a datarate adaptation, 68 | * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according 69 | * to the following table: 70 | * 71 | * Transmission nb | Data Rate 72 | * ----------------|----------- 73 | * 1 (first) | DR 74 | * 2 | DR 75 | * 3 | max(DR-1,0) 76 | * 4 | max(DR-1,0) 77 | * 5 | max(DR-2,0) 78 | * 6 | max(DR-2,0) 79 | * 7 | max(DR-3,0) 80 | * 8 | max(DR-3,0) 81 | * 82 | * Note, that if NbTrials is set to 1 or 2, the MAC will not decrease 83 | * the datarate, in case the LoRaMAC layer did not receive an acknowledgment 84 | */ 85 | uint8_t confirmedNbTrials = 8; 86 | 87 | /*LoraWan debug level, select in arduino IDE tools. 88 | * None : print basic info. 89 | * Freq : print Tx and Rx freq, DR info. 90 | * Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info. 91 | * Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt, MCU sleep and MCU wake info. 92 | */ 93 | uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; 94 | 95 | /*LoraWan region, select in arduino IDE tools*/ 96 | LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; 97 | 98 | 99 | static void prepareTxFrame( uint8_t port ) 100 | { 101 | appDataSize = 4; 102 | appData[0] = 0x00; 103 | appData[1] = 0x01; 104 | appData[2] = 0x02; 105 | appData[3] = 0x03; 106 | } 107 | 108 | // Add your initialization code here 109 | void setup() 110 | { 111 | if(mcuStarted==0) 112 | { 113 | LoRaWAN.displayMcuInit(); 114 | } 115 | Serial.begin(115200); 116 | while (!Serial); 117 | SPI.begin(SCK,MISO,MOSI,SS); 118 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 119 | delay(100); 120 | deviceState = DEVICE_STATE_INIT; 121 | } 122 | 123 | // The loop function is called in an endless loop 124 | void loop() 125 | { 126 | switch( deviceState ) 127 | { 128 | case DEVICE_STATE_INIT: 129 | { 130 | #if(LORAWAN_DEVEUI_AUTO) 131 | LoRaWAN.generateDeveuiByChipID(); 132 | #endif 133 | LoRaWAN.init(loraWanClass,loraWanRegion); 134 | break; 135 | } 136 | case DEVICE_STATE_JOIN: 137 | { 138 | LoRaWAN.displayJoining(); 139 | LoRaWAN.join(); 140 | break; 141 | } 142 | case DEVICE_STATE_SEND: 143 | { 144 | LoRaWAN.displaySending(); 145 | prepareTxFrame( appPort ); 146 | LoRaWAN.send(loraWanClass); 147 | deviceState = DEVICE_STATE_CYCLE; 148 | break; 149 | } 150 | case DEVICE_STATE_CYCLE: 151 | { 152 | // Schedule next packet transmission 153 | txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 154 | LoRaWAN.cycle(txDutyCycleTime); 155 | deviceState = DEVICE_STATE_SLEEP; 156 | break; 157 | } 158 | case DEVICE_STATE_SLEEP: 159 | { 160 | LoRaWAN.displayAck(); 161 | esp_sleep_enable_ext0_wakeup(INT_PIN,0); 162 | LoRaWAN.sleep(loraWanClass,debugLevel); 163 | break; 164 | } 165 | default: 166 | { 167 | deviceState = DEVICE_STATE_INIT; 168 | break; 169 | } 170 | } 171 | } -------------------------------------------------------------------------------- /examples/OTAA_OLED_interrupt_CLASS_C/OTAA_OLED_interrupt_CLASS_C.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A 3 | * 4 | * Function summary: 5 | * 6 | * - use internal RTC(150KHz); 7 | * 8 | * - Include stop mode and deep sleep mode; 9 | * 10 | * - 15S data send cycle; 11 | * 12 | * - Informations output via serial(115200); 13 | * 14 | * - Only ESP32 + LoRa series boards can use this library, need a license 15 | * to make the code run(check you license here: http://www.heltec.cn/search ); 16 | * 17 | * You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h" 18 | * 19 | * HelTec AutoMation, Chengdu, China. 20 | * 成都惠利特自动化科技有限公司 21 | * https://heltec.org 22 | * support@heltec.cn 23 | * 24 | *this project also release in GitHub: 25 | *https://github.com/HelTecAutomation/ESP32_LoRaWAN 26 | */ 27 | 28 | #include 29 | #include "Arduino.h" 30 | 31 | #define INT_PIN 12 32 | /*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */ 33 | uint32_t license[4] = {0x0C6EE449, 0x446722FE, 0x6758DEB6, 0x0C4A735E}; 34 | /* OTAA para*/ 35 | uint8_t DevEui[] = { 0x22, 0x32, 0x33, 0x00, 0x00, 0x88, 0x88, 0x02 }; 36 | uint8_t AppEui[] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0xB1, 0x8A }; 37 | uint8_t AppKey[] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01 }; 38 | 39 | /* ABP para*/ 40 | uint8_t NwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 }; 41 | uint8_t AppSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef,0x67 }; 42 | uint32_t DevAddr = ( uint32_t )0x007e6ae1; 43 | 44 | /*LoraWan channelsmask, default channels 0-7*/ 45 | uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; 46 | 47 | /*LoraWan Class, Class A and Class C are supported*/ 48 | DeviceClass_t loraWanClass = CLASS_C; 49 | 50 | /*the application data transmission duty cycle. value in [ms].*/ 51 | uint32_t appTxDutyCycle = 3600*24*1000; 52 | 53 | /*OTAA or ABP*/ 54 | bool overTheAirActivation = true; 55 | 56 | /*ADR enable*/ 57 | bool loraWanAdr = true; 58 | 59 | /* Indicates if the node is sending confirmed or unconfirmed messages */ 60 | bool isTxConfirmed = true; 61 | 62 | /* Application port */ 63 | uint8_t appPort = 2; 64 | 65 | /*! 66 | * Number of trials to transmit the frame, if the LoRaMAC layer did not 67 | * receive an acknowledgment. The MAC performs a datarate adaptation, 68 | * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according 69 | * to the following table: 70 | * 71 | * Transmission nb | Data Rate 72 | * ----------------|----------- 73 | * 1 (first) | DR 74 | * 2 | DR 75 | * 3 | max(DR-1,0) 76 | * 4 | max(DR-1,0) 77 | * 5 | max(DR-2,0) 78 | * 6 | max(DR-2,0) 79 | * 7 | max(DR-3,0) 80 | * 8 | max(DR-3,0) 81 | * 82 | * Note, that if NbTrials is set to 1 or 2, the MAC will not decrease 83 | * the datarate, in case the LoRaMAC layer did not receive an acknowledgment 84 | */ 85 | uint8_t confirmedNbTrials = 1; 86 | 87 | /*LoraWan debug level, select in arduino IDE tools. 88 | * None : print basic info. 89 | * Freq : print Tx and Rx freq, DR info. 90 | * Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info. 91 | * Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt, MCU sleep and MCU wake info. 92 | */ 93 | uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; 94 | 95 | /*LoraWan region, select in arduino IDE tools*/ 96 | LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; 97 | 98 | 99 | static void prepareTxFrame( uint8_t port ) 100 | { 101 | appDataSize = 4; 102 | appData[0] = 0x00; 103 | appData[1] = 0x01; 104 | appData[2] = 0x02; 105 | appData[3] = 0x03; 106 | } 107 | 108 | void keyDown() 109 | { 110 | delay(10); 111 | if(digitalRead(INT_PIN)==1 && IsLoRaMacNetworkJoined) 112 | { 113 | deviceState = DEVICE_STATE_SEND; 114 | } 115 | } 116 | // Add your initialization code here 117 | void setup() 118 | { 119 | if(mcuStarted==0) 120 | { 121 | LoRaWAN.displayMcuInit(); 122 | } 123 | Serial.begin(115200); 124 | while (!Serial); 125 | SPI.begin(SCK,MISO,MOSI,SS); 126 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 127 | delay(100); 128 | pinMode(INT_PIN,INPUT_PULLUP); 129 | attachInterrupt(INT_PIN,keyDown,RISING); 130 | deviceState = DEVICE_STATE_INIT; 131 | } 132 | 133 | 134 | // The loop function is called in an endless loop 135 | void loop() 136 | { 137 | switch( deviceState ) 138 | { 139 | case DEVICE_STATE_INIT: 140 | { 141 | #if(LORAWAN_DEVEUI_AUTO) 142 | LoRaWAN.generateDeveuiByChipID(); 143 | #endif 144 | LoRaWAN.init(loraWanClass,loraWanRegion); 145 | break; 146 | } 147 | case DEVICE_STATE_JOIN: 148 | { 149 | LoRaWAN.displayJoining(); 150 | LoRaWAN.join(); 151 | break; 152 | } 153 | case DEVICE_STATE_SEND: 154 | { 155 | LoRaWAN.displaySending(); 156 | prepareTxFrame( appPort ); 157 | LoRaWAN.send(loraWanClass); 158 | deviceState = DEVICE_STATE_CYCLE; 159 | break; 160 | } 161 | case DEVICE_STATE_CYCLE: 162 | { 163 | // Schedule next packet transmission 164 | txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 165 | LoRaWAN.cycle(txDutyCycleTime); 166 | deviceState = DEVICE_STATE_SLEEP; 167 | break; 168 | } 169 | case DEVICE_STATE_SLEEP: 170 | { 171 | LoRaWAN.displayAck(); 172 | LoRaWAN.sleep(loraWanClass,debugLevel); 173 | break; 174 | } 175 | default: 176 | { 177 | deviceState = DEVICE_STATE_INIT; 178 | break; 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /examples/Sensor/LoRaWAN_HDC1080/LoRaWAN_HDC1080.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A 3 | * 4 | * Function summary: 5 | * 6 | * - use internal RTC(150KHz); 7 | * 8 | * - Include stop mode and deep sleep mode; 9 | * 10 | * - 15S data send cycle; 11 | * 12 | * - Informations output via serial(115200); 13 | * 14 | * - Only ESP32 + LoRa series boards can use this library, need a license 15 | * to make the code run(check you license here: http://www.heltec.cn/search/); 16 | * 17 | * You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h" 18 | * 19 | * HelTec AutoMation, Chengdu, China. 20 | * 成都惠利特自动化科技有限公司 21 | * https://heltec.org 22 | * support@heltec.cn 23 | * 24 | *this project also release in GitHub: 25 | *https://github.com/HelTecAutomation/ESP32_LoRaWAN 26 | */ 27 | 28 | #include 29 | #include "Arduino.h" 30 | #include "sensor/HDC1080.h" 31 | #include "esp32-hal-adc.h" 32 | 33 | /*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */ 34 | uint32_t license[4] = {0xD5397DF0, 0x8573F814, 0x7A38C73D, 0x48E68607}; 35 | 36 | /* OTAA para*/ 37 | uint8_t DevEui[] = { 0x22, 0x32, 0x33, 0x00, 0x00, 0x88, 0x88, 0x02 }; 38 | uint8_t AppEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 39 | uint8_t AppKey[] = { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01 }; 40 | 41 | /* ABP para*/ 42 | uint8_t NwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda,0x85 }; 43 | uint8_t AppSKey[] = { 0xd7, 0x2c, 0x78, 0x75, 0x8c, 0xdc, 0xca, 0xbf, 0x55, 0xee, 0x4a, 0x77, 0x8d, 0x16, 0xef,0x67 }; 44 | uint32_t DevAddr = ( uint32_t )0x007e6ae1; 45 | 46 | /*LoraWan channelsmask, default channels 0-7*/ 47 | uint16_t userChannelsMask[6]={ 0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000 }; 48 | 49 | /*LoraWan Class, Class A and Class C are supported*/ 50 | DeviceClass_t loraWanClass = CLASS_A; 51 | 52 | /*the application data transmission duty cycle. value in [ms].*/ 53 | uint32_t appTxDutyCycle = 15000; 54 | 55 | /*OTAA or ABP*/ 56 | bool overTheAirActivation = true; 57 | 58 | /*ADR enable*/ 59 | bool loraWanAdr = true; 60 | 61 | /* Indicates if the node is sending confirmed or unconfirmed messages */ 62 | bool isTxConfirmed = true; 63 | 64 | /* Application port */ 65 | uint8_t appPort = 2; 66 | 67 | /*! 68 | * Number of trials to transmit the frame, if the LoRaMAC layer did not 69 | * receive an acknowledgment. The MAC performs a datarate adaptation, 70 | * according to the LoRaWAN Specification V1.0.2, chapter 18.4, according 71 | * to the following table: 72 | * 73 | * Transmission nb | Data Rate 74 | * ----------------|----------- 75 | * 1 (first) | DR 76 | * 2 | DR 77 | * 3 | max(DR-1,0) 78 | * 4 | max(DR-1,0) 79 | * 5 | max(DR-2,0) 80 | * 6 | max(DR-2,0) 81 | * 7 | max(DR-3,0) 82 | * 8 | max(DR-3,0) 83 | * 84 | * Note, that if NbTrials is set to 1 or 2, the MAC will not decrease 85 | * the datarate, in case the LoRaMAC layer did not receive an acknowledgment 86 | */ 87 | uint8_t confirmedNbTrials = 8; 88 | 89 | /*LoraWan debug level, select in arduino IDE tools. 90 | * None : print basic info. 91 | * Freq : print Tx and Rx freq, DR info. 92 | * Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info. 93 | * Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt and MCU deepsleep info. 94 | */ 95 | uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL; 96 | 97 | /*LoraWan region, select in arduino IDE tools*/ 98 | LoRaMacRegion_t loraWanRegion = ACTIVE_REGION; 99 | 100 | HDC1080 hdc1080; 101 | static void prepareTxFrame( uint8_t port ) 102 | { 103 | /*appData size is LORAWAN_APP_DATA_MAX_SIZE which is defined in "commissioning.h". 104 | *appDataSize max value is LORAWAN_APP_DATA_MAX_SIZE. 105 | *if enabled AT, don't modify LORAWAN_APP_DATA_MAX_SIZE, it may cause system hanging or failure. 106 | *if disabled AT, LORAWAN_APP_DATA_MAX_SIZE can be modified, the max value is reference to lorawan region and SF. 107 | *for example, if use REGION_CN470, 108 | *the max value for different DR can be found in MaxPayloadOfDatarateCN470 refer to DataratesCN470 and BandwidthsCN470 in "RegionCN470.h". 109 | */ 110 | pinMode(Vext,OUTPUT); 111 | digitalWrite(Vext,LOW); 112 | uint16_t batteryVoltage = analogRead(37)*3.046; 113 | hdc1080.begin(0x40); 114 | float temperature = (float)(hdc1080.readTemperature()); 115 | float humidity = (float)(hdc1080.readHumidity()); 116 | hdc1080.end(); 117 | digitalWrite(Vext,HIGH); 118 | unsigned char *puc; 119 | 120 | puc = (unsigned char *)(&temperature); 121 | appDataSize = 10; 122 | appData[0] = puc[0]; 123 | appData[1] = puc[1]; 124 | appData[2] = puc[2]; 125 | appData[3] = puc[3]; 126 | 127 | puc = (unsigned char *)(&humidity); 128 | appData[4] = puc[0]; 129 | appData[5] = puc[1]; 130 | appData[6] = puc[2]; 131 | appData[7] = puc[3]; 132 | 133 | appData[8] = (uint8_t)(batteryVoltage>>8); 134 | appData[9] = (uint8_t)batteryVoltage; 135 | 136 | Serial.print("T="); 137 | Serial.print(temperature); 138 | Serial.print("C, RH="); 139 | Serial.print(humidity); 140 | Serial.print("%,"); 141 | Serial.print("BatteryVoltage:"); 142 | Serial.println(batteryVoltage); 143 | } 144 | 145 | // Add your initialization code here 146 | void setup() 147 | { 148 | Serial.begin(115200); 149 | while (!Serial); 150 | SPI.begin(SCK,MISO,MOSI,SS); 151 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 152 | 153 | adcAttachPin(37); 154 | analogSetClockDiv(255); // 1338mS 155 | 156 | deviceState = DEVICE_STATE_INIT; 157 | } 158 | 159 | // The loop function is called in an endless loop 160 | void loop() 161 | { 162 | switch( deviceState ) 163 | { 164 | case DEVICE_STATE_INIT: 165 | { 166 | #if(LORAWAN_DEVEUI_AUTO) 167 | LoRaWAN.generateDeveuiByChipID(); 168 | #endif 169 | LoRaWAN.init(loraWanClass,loraWanRegion); 170 | break; 171 | } 172 | case DEVICE_STATE_JOIN: 173 | { 174 | LoRaWAN.join(); 175 | break; 176 | } 177 | case DEVICE_STATE_SEND: 178 | { 179 | prepareTxFrame( appPort ); 180 | LoRaWAN.send(loraWanClass); 181 | deviceState = DEVICE_STATE_CYCLE; 182 | break; 183 | } 184 | case DEVICE_STATE_CYCLE: 185 | { 186 | // Schedule next packet transmission 187 | txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); 188 | LoRaWAN.cycle(txDutyCycleTime); 189 | deviceState = DEVICE_STATE_SLEEP; 190 | break; 191 | } 192 | case DEVICE_STATE_SLEEP: 193 | { 194 | LoRaWAN.sleep(loraWanClass,debugLevel); 195 | break; 196 | } 197 | default: 198 | { 199 | deviceState = DEVICE_STATE_INIT; 200 | break; 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /examples/pingpong/pingpong.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A 3 | * 4 | * Function summary: 5 | * 6 | * - use internal RTC(150KHz); 7 | * 8 | * - Include stop mode and deep sleep mode; 9 | * 10 | * - 15S data send cycle; 11 | * 12 | * - Informations output via serial(115200); 13 | * 14 | * - Only ESP32 + LoRa series boards can use this library, need a license 15 | * to make the code run(check you license here: http://www.heltec.cn/search/); 16 | * 17 | * You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h" 18 | * 19 | * HelTec AutoMation, Chengdu, China. 20 | * 成都惠利特自动化科技有限公司 21 | * https://heltec.org 22 | * support@heltec.cn 23 | * 24 | *this project also release in GitHub: 25 | *https://github.com/HelTecAutomation/ESP32_LoRaWAN 26 | */ 27 | 28 | #include 29 | #include "Arduino.h" 30 | 31 | 32 | #define RF_FREQUENCY 868000000 // Hz 33 | 34 | #define TX_OUTPUT_POWER 15 // dBm 35 | 36 | #define LORA_BANDWIDTH 0 // [0: 125 kHz, 37 | // 1: 250 kHz, 38 | // 2: 500 kHz, 39 | // 3: Reserved] 40 | #define LORA_SPREADING_FACTOR 7 // [SF7..SF12] 41 | #define LORA_CODINGRATE 1 // [1: 4/5, 42 | // 2: 4/6, 43 | // 3: 4/7, 44 | // 4: 4/8] 45 | #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx 46 | #define LORA_SYMBOL_TIMEOUT 0 // Symbols 47 | #define LORA_FIX_LENGTH_PAYLOAD_ON false 48 | #define LORA_IQ_INVERSION_ON false 49 | 50 | 51 | #define RX_TIMEOUT_VALUE 1000 52 | #define BUFFER_SIZE 30 // Define the payload size here 53 | 54 | char txpacket[BUFFER_SIZE]; 55 | char rxpacket[BUFFER_SIZE]; 56 | 57 | static RadioEvents_t RadioEvents; 58 | void OnTxDone( void ); 59 | void OnTxTimeout( void ); 60 | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); 61 | 62 | typedef enum 63 | { 64 | STATUS_LOWPOWER, 65 | STATUS_RX, 66 | STATUS_TX 67 | }States_t; 68 | 69 | 70 | int16_t txNumber; 71 | States_t state; 72 | bool sleepMode = false; 73 | int16_t Rssi,rxSize; 74 | 75 | uint32_t license[4] = {0xD5397DF0, 0x8573F814, 0x7A38C73D, 0x48E68607}; 76 | 77 | // Add your initialization code here 78 | void setup() 79 | { 80 | Serial.begin(115200); 81 | while (!Serial); 82 | SPI.begin(SCK,MISO,MOSI,SS); 83 | Mcu.init(SS,RST_LoRa,DIO0,DIO1,license); 84 | 85 | 86 | txNumber=0; 87 | Rssi=0; 88 | 89 | RadioEvents.TxDone = OnTxDone; 90 | RadioEvents.TxTimeout = OnTxTimeout; 91 | RadioEvents.RxDone = OnRxDone; 92 | 93 | Radio.Init( &RadioEvents ); 94 | Radio.SetChannel( RF_FREQUENCY ); 95 | Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, 96 | LORA_SPREADING_FACTOR, LORA_CODINGRATE, 97 | LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, 98 | true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); 99 | 100 | Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, 101 | LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, 102 | LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 103 | 0, true, 0, 0, LORA_IQ_INVERSION_ON, true ); 104 | state=STATUS_TX; 105 | } 106 | 107 | 108 | void loop() 109 | { 110 | switch(state) 111 | { 112 | case STATUS_TX: 113 | delay(1000); 114 | txNumber++; 115 | sprintf(txpacket,"%s","hello"); 116 | sprintf(txpacket+strlen(txpacket),"%d",txNumber); 117 | sprintf(txpacket+strlen(txpacket),"%s"," Rssi : "); 118 | sprintf(txpacket+strlen(txpacket),"%d",Rssi); 119 | 120 | Serial.printf("\r\nsending packet \"%s\" , length %d\r\n",txpacket, strlen(txpacket)); 121 | 122 | Radio.Send( (uint8_t *)txpacket, strlen(txpacket) ); 123 | state=STATUS_LOWPOWER; 124 | break; 125 | case STATUS_RX: 126 | Serial.println("into RX mode"); 127 | Radio.Rx( 0 ); 128 | state=STATUS_LOWPOWER; 129 | break; 130 | case STATUS_LOWPOWER: 131 | LoRaWAN.sleep(CLASS_C,0); 132 | break; 133 | default: 134 | break; 135 | } 136 | } 137 | 138 | void OnTxDone( void ) 139 | { 140 | Serial.print("TX done......"); 141 | state=STATUS_RX; 142 | } 143 | 144 | void OnTxTimeout( void ) 145 | { 146 | Radio.Sleep( ); 147 | Serial.print("TX Timeout......"); 148 | state=STATUS_TX; 149 | } 150 | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) 151 | { 152 | Rssi=rssi; 153 | rxSize=size; 154 | memcpy(rxpacket, payload, size ); 155 | rxpacket[size]='\0'; 156 | Radio.Sleep( ); 157 | 158 | Serial.printf("\r\nreceived packet \"%s\" with Rssi %d , length %d\r\n",rxpacket,Rssi,rxSize); 159 | Serial.println("wait to send next packet"); 160 | 161 | state=STATUS_TX; 162 | } 163 | -------------------------------------------------------------------------------- /idf_component.yml: -------------------------------------------------------------------------------- 1 | description: "LoRaWAN library for ESP32 + LoRa boards made by heltec" 2 | url: "https://github.com/HelTecAutomation/ESP32_LoRaWAN.git" 3 | targets: 4 | - esp32 5 | tags: 6 | - arduino 7 | files: 8 | include: 9 | - "src/**/*" 10 | - "examples/**/*" 11 | - "img/**/*" 12 | - "CMakeLists.txt" 13 | - "Kconfig.projbuild" 14 | exclude: 15 | - "**/*" 16 | -------------------------------------------------------------------------------- /img/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelTecAutomation/ESP32_LoRaWAN/7b5d52b4666c90b9aa0dfa15189678d2d7e12b54/img/01.png -------------------------------------------------------------------------------- /img/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelTecAutomation/ESP32_LoRaWAN/7b5d52b4666c90b9aa0dfa15189678d2d7e12b54/img/02.png -------------------------------------------------------------------------------- /img/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelTecAutomation/ESP32_LoRaWAN/7b5d52b4666c90b9aa0dfa15189678d2d7e12b54/img/03.png -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ESP32_LoRaWAN 2 | version=2.1.1 3 | author=HelTec 4 | maintainer=Harry 5 | sentence=LoRaWAN library for ESP32 + LoRa boards made by heltec 6 | paragraph=See more on http://heltec.cn 7 | category=Device Control 8 | url=https://github.com/HelTecAutomation/ESP32_LoRaWAN 9 | architectures=esp32 10 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # This Library had been Stoped to maintenance 2 | 3 | - **The library had stop maintenance on December 20th, 2022**, and will not compatible with the [Heltec WiFi Kit Series (V0.0.7)](https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series/releases/tag/0.0.7) or newer development framework. 4 | 5 | - **A full functions of LoRaWAN library already included in [Heltec ESP32 library](https://github.com/HelTecAutomation/Heltec_ESP32).** We strongly recommend using the [Heltec ESP32 library](https://github.com/HelTecAutomation/Heltec_ESP32) for your new project development. 6 | 7 | - If you have any questions, please fell free to contact us: support@heltec.cn. 8 | 9 | 10 | 11 | 12 | ## Contents 13 | 14 | - [The Overview](#the-overview) 15 | - [Installing](#installing) 16 | - [Features](#features) 17 | - [Test information](#test-information) 18 | - [How to use this library](#how-to-use-this-library) 19 | - [Contact us](#contact-us) 20 | 21 | # The Overview 22 | 23 | - **This library must work with newest [Heltec_ESP32 development framework](https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series)** 24 | - *For now, new features still not included in the release version, must install this framework via Git.* 25 | - This library is make LoRaWAN 1.0.2 protocol running with ESP32. Only support the ESP32 + LoRa series products made by [HelTec Automation(TM)](heltec.org), and a [LoRa gateway](https://heltec.org/proudct_center/lora/lora-gateway/) is must needed; 26 | - LoRaWAN relevant parameters are defined in the .ino file; 27 | - This library is transplanted from https://github.com/Lora-net/LoRaMac-node; 28 | - Use RTC and deep sleep mode supported, only a few milliseconds wake up in a cycle; 29 | - **[Heltec LoRa Node Family]([Heltec Automation(TM) products index page](https://docs.heltec.cn/#/en/products/lora/lora_node/heltec_lora_node_list)).** 30 | 31 | 32 | # Installing 33 | 34 | To install this library: 35 | 36 | - install it using the Arduino Library manager ("Sketch" -> "Include Library" -> "Manage Libraries..."), or 37 | - download a zip file from GitHub using the "Download ZIP" button and install it using the IDE ("Sketch" -> "Include Library" -> "Add .ZIP Library..." 38 | - clone this git repository into your sketchbook/libraries folder. 39 | 40 | For more info, see https://www.arduino.cc/en/Guide/Libraries 41 | 42 | # Features 43 | 44 | The `ESP32_LoRaWAN` library provides a fairly complete LoRaWAN Class A and Class C implementation. The latest update (February 10th, 2020) has full region support (KR920, AS923, US915, etc.). 45 | 46 | The following functions are included: 47 | - LoRaWAN protocol V1.0.2 Class A and Class C; 48 | - Use ESP32's internal RTC (15KHz); 49 | - All [ESP32 + LoRa](https://heltec.org/proudct_center/lora/lora-node/) boards made by [Heltec Automation(TM)](heltec.org) can use this library; 50 | - Support deep sleep and stop mode; 51 | - Receive and print downlink payload; 52 | - Print and OLED show downlink data length and RSSI; 53 | - An unique license related to Chip ID is needed, you can check your license here: http://www.heltec.cn/search/ 54 | 55 | # Test information 56 | 57 | ![](img/02.png) 58 | - Gateway: [HT-M01 Mini LoRa Gateway](http://www.heltec.cn/project/ht-m01-lora-gateway/?lang=en) + Raspberry Pi Zero W 59 | - Node: [WIFI LoRa 32 V2](https://heltec.org/project/wifi-lora-32/), [Wireless Stick](https://heltec.org/project/wireless-stick/), [Wireless Stick Lite](https://heltec.org/project/wireless-stick-lite/) 60 | - Lora Server: 61 | - [Heltec Cloud Server](http://cloud.heltec.org/); 62 | - [TTN](https://www.thethingsnetwork.org/). 63 | - Arduino 1.8.10 64 | 65 | | working band | status | 66 | | :----------------: | :------------:| 67 | | EU433 | not test | 68 | | CN470 | work well | 69 | | EU863 | work well | 70 | | US915 | work well | 71 | | AU916 | work well | 72 | | CN779 | not test | 73 | | AS923 | not test | 74 | | KR920 | not test | 75 | | IN865 | not test | 76 | | US915_HYBRID | not test | 77 | 78 | **What certainly works:** 79 | 80 | - Sending payload to a LoRa gateway via LoRaWAN protocol; 81 | - Encryption and message integrity checking; 82 | - Over-the-air activation (OTAA / joining); 83 | - Deep sleep and wake up; 84 | - Class A operation; 85 | - Class C operation; 86 | - ABP mode. 87 | 88 | **What has not been tested:** 89 | 90 | - Receiving downlink packets in the RX2 window. 91 | 92 | # How to use this library 93 | The only different with a common Arduino library is need a unique license. It's relate to ESP32 Chip ID. 94 | 95 | ### How to get your board's Chip ID? 96 | - Use this simple example to read your Chip ID: https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series/tree/master/esp32/libraries/ESP32/examples/ChipID/GetChipID 97 | 98 | ### How to get the unique license? 99 | - http://www.heltec.cn/search/ Open this page and input your ChipID 100 | 101 | Only the boards made after August 2018 can be checked from this page, if you have a former version, you can mail to support@heltec.cn and improve you already have a Heltec Automation made board. 102 | 103 | ### Choose the right working band you need 104 | 105 | Choose working band you need In the Arduino tools menu: 106 | 107 | ![](img/01.png) 108 | 109 | 110 | 111 | For more details about how to use this library, please refer to this document: 112 | 113 | [ESP32 LoRaWAN library usage](https://heltec-automation-docs.readthedocs.io/en/latest/esp32/lorawan/index.html). 114 | 115 |   116 | 117 | ### How to Use This Library in Platform.io? 118 | 119 | The options in the Tools menu is relate to the [Heltec ESP32 development framework](https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series), but in the Platform.io, it's use original [Espressif ESP32 framework](https://github.com/espressif/arduino-esp32). So we need additional definition the `build_flags` in `platformio.ini` file. 120 | 121 | ```shell 122 | build_flags = 123 | -D REGION_CN470 124 | -D ACTIVE_REGION=LORAMAC_REGION_CN470 125 | -D LoRaWAN_DEBUG_LEVEL=0 126 | ``` 127 | 128 | ![](img/03.png) 129 | 130 | 131 | # Contact us 132 | - **Website:[https://heltec.org](https://heltec.org/)** 133 | - **Document Page: [https://docs.heltec.cn](https://docs.heltec.cn)** 134 | - **Forum: [http://community.heltec.cn/](http://community.heltec.cn/)** 135 | - **Twitter: [https://twitter.com/HeltecOrg](https://twitter.com/HeltecOrg)** 136 | - **Face Book: [https://www.facebook.com/heltec.automation.5](https://www.facebook.com/heltec.automation.5)** 137 | 138 | # Issue/Bug report template 139 | Before reporting an issue, make sure you've searched for similar one that was already created. Also make sure to go through all the issues labeled as [for reference](https://github.com/HelTecAutomation/ESP32_LoRaWAN/issues). 140 | 141 | Also you can talk in our forum: [http://community.heltec.cn/](http://community.heltec.cn/) 142 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## 2 | ## ______ _ 3 | ## / _____) _ | | 4 | ## ( (____ _____ ____ _| |_ _____ ____| |__ 5 | ## \____ \| ___ | (_ _) ___ |/ ___) _ \ 6 | ## _____) ) ____| | | || |_| ____( (___| | | | 7 | ## (______/|_____)_|_|_| \__)_____)\____)_| |_| 8 | ## (C)2013-2017 Semtech 9 | ## ___ _____ _ ___ _ _____ ___ ___ ___ ___ 10 | ## / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 11 | ## \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 12 | ## |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 13 | ## embedded.connectivity.solutions.============== 14 | ## 15 | ## License: Revised BSD License, see LICENSE.TXT file included in the project 16 | ## Authors: Johannes Bruder (STACKFORCE), Miguel Luis (Semtech) 17 | ## 18 | project(mac) 19 | cmake_minimum_required(VERSION 3.6) 20 | 21 | #--------------------------------------------------------------------------------------- 22 | # Options 23 | #--------------------------------------------------------------------------------------- 24 | 25 | # Allow selection of region 26 | option(REGION_EU868 "Region EU868" ON) 27 | option(REGION_US915 "Region US915" OFF) 28 | option(REGION_CN779 "Region CN779" OFF) 29 | option(REGION_EU433 "Region EU433" OFF) 30 | option(REGION_AU915 "Region AU915" OFF) 31 | option(REGION_AS923 "Region AS923" OFF) 32 | option(REGION_CN470 "Region CN470" OFF) 33 | option(REGION_KR920 "Region KR920" OFF) 34 | option(REGION_IN865 "Region IN865" OFF) 35 | option(REGION_US915_HYBRID "Region US915 in hybrid mode" OFF) 36 | set(REGION_LIST REGION_EU868 REGION_US915 REGION_CN779 REGION_EU433 REGION_AU915 REGION_AS923 REGION_CN470 REGION_KR920 REGION_IN865 REGION_US915_HYBRID) 37 | 38 | #--------------------------------------------------------------------------------------- 39 | # Target 40 | #--------------------------------------------------------------------------------------- 41 | 42 | file(GLOB ${PROJECT_NAME}_SOURCES 43 | "${CMAKE_CURRENT_SOURCE_DIR}/*.c" 44 | "${CMAKE_CURRENT_SOURCE_DIR}/region/*.c" 45 | ) 46 | 47 | add_library(${PROJECT_NAME} OBJECT EXCLUDE_FROM_ALL ${${PROJECT_NAME}_SOURCES}) 48 | 49 | # Loops through all regions and add compile time definitions for the enabled ones. 50 | foreach( REGION ${REGION_LIST} ) 51 | if(${REGION}) 52 | target_compile_definitions(${PROJECT_NAME} PUBLIC -D"${REGION}") 53 | endif() 54 | endforeach() 55 | 56 | add_dependencies(${PROJECT_NAME} board) 57 | 58 | target_include_directories( ${PROJECT_NAME} PUBLIC 59 | ${CMAKE_CURRENT_SOURCE_DIR} 60 | ${CMAKE_CURRENT_SOURCE_DIR}/region 61 | $ 62 | $ 63 | $ 64 | ) 65 | 66 | set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 11) 67 | -------------------------------------------------------------------------------- /src/Commissioning.h: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2015 Semtech 8 | 9 | Description: End device commissioning parameters 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | 16 | #ifndef __LORA_COMMISSIONING_H__ 17 | #define __LORA_COMMISSIONING_H__ 18 | 19 | /*! 20 | * User application data buffer size 21 | */ 22 | #define LORAWAN_APP_DATA_MAX_SIZE 128 23 | 24 | /*! 25 | * Indicates if the end-device is to be connected to a private or public network 26 | */ 27 | #define LORAWAN_PUBLIC_NETWORK true 28 | 29 | /*! 30 | * Current network ID 31 | */ 32 | #define LORAWAN_NETWORK_ID ( uint32_t )0 33 | 34 | #endif // __LORA_COMMISSIONING_H__ 35 | -------------------------------------------------------------------------------- /src/ESP32_LoRaWAN.h: -------------------------------------------------------------------------------- 1 | #ifndef LORA_H 2 | #define LORA_H 3 | 4 | #include 5 | #include "SPI.h" 6 | #include "board.h" 7 | #include "Commissioning.h" 8 | #include "Mcu.h" 9 | #include "utilities.h" 10 | #include "board-config.h" 11 | #include "LoRaMac.h" 12 | #include "Commissioning.h" 13 | #include "rtc-board.h" 14 | #include "delay.h" 15 | #include // Only needed for Arduino 1.6.5 and earlier 16 | #include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` 17 | 18 | enum eDeviceState 19 | { 20 | DEVICE_STATE_INIT, 21 | DEVICE_STATE_JOIN, 22 | DEVICE_STATE_SEND, 23 | DEVICE_STATE_CYCLE, 24 | DEVICE_STATE_SLEEP 25 | }; 26 | 27 | 28 | #define APP_TX_DUTYCYCLE_RND 1000 29 | 30 | class LoRaWanClass{ 31 | public: 32 | void init(DeviceClass_t classMode,LoRaMacRegion_t region); 33 | void join(); 34 | void send(DeviceClass_t classMode); 35 | void cycle(uint32_t dutyCycle); 36 | void sleep(DeviceClass_t classMode,uint8_t debugLevel); 37 | void displayJoining(); 38 | void displayJoined(); 39 | void displaySending(); 40 | void displayAck(); 41 | void displayMcuInit(); 42 | void generateDeveuiByChipID(); 43 | }; 44 | 45 | extern enum eDeviceState deviceState; 46 | extern uint8_t appPort; 47 | extern uint32_t txDutyCycleTime; 48 | extern uint8_t appData[LORAWAN_APP_DATA_MAX_SIZE]; 49 | extern uint8_t appDataSize; 50 | extern uint32_t txDutyCycleTime; 51 | extern bool overTheAirActivation; 52 | extern LoRaMacRegion_t loraWanRegion; 53 | extern bool loraWanAdr; 54 | extern bool isTxConfirmed; 55 | extern uint32_t appTxDutyCycle; 56 | extern uint8_t confirmedNbTrials; 57 | extern DeviceClass_t loraWanClass; 58 | extern uint8_t DevEui[]; 59 | extern uint8_t AppEui[]; 60 | extern uint8_t AppKey[]; 61 | extern uint8_t NwkSKey[]; 62 | extern uint8_t AppSKey[]; 63 | extern uint32_t DevAddr; 64 | extern uint8_t idDisplayJoined; 65 | extern uint8_t ifDisplayAck; 66 | extern uint16_t userChannelsMask[6]; 67 | 68 | extern LoRaWanClass LoRaWAN; 69 | 70 | #if defined( WIFI_LoRa_32 ) || defined( WIFI_LoRa_32_V2 ) || defined( Wireless_Stick ) 71 | extern SSD1306 Display; 72 | #endif 73 | 74 | #ifdef __cplusplus 75 | extern "C"{ 76 | #endif 77 | 78 | #ifdef __cplusplus 79 | } // extern "C" 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/LoRaMacConfirmQueue.c: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | ___ _____ _ ___ _ _____ ___ ___ ___ ___ 9 | / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 10 | \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 11 | |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 12 | embedded.connectivity.solutions=============== 13 | 14 | Description: LoRa MAC confirm queue implementation 15 | 16 | License: Revised BSD License, see LICENSE.TXT file include in the project 17 | 18 | Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 19 | */ 20 | #include 21 | #include 22 | #include 23 | 24 | #include "timer.h" 25 | #include "utilities.h" 26 | #include "LoRaMac.h" 27 | #include "LoRaMacConfirmQueue.h" 28 | 29 | 30 | static LoRaMacPrimitives_t* Primitives; 31 | 32 | /*! 33 | * MlmeConfirm queue data structure 34 | */ 35 | static MlmeConfirmQueue_t MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN]; 36 | 37 | /*! 38 | * Counts the number of MlmeConfirms to process 39 | */ 40 | static uint8_t MlmeConfirmQueueCnt; 41 | 42 | /*! 43 | * Pointer to the first element of the ring buffer 44 | */ 45 | MlmeConfirmQueue_t* BufferStart; 46 | 47 | /*! 48 | * Pointer to the last element of the ring buffer 49 | */ 50 | MlmeConfirmQueue_t* BufferEnd; 51 | 52 | /*! 53 | * Variable which holds a common status 54 | */ 55 | LoRaMacEventInfoStatus_t CommonStatus; 56 | 57 | 58 | static MlmeConfirmQueue_t* IncreaseBufferPointer( MlmeConfirmQueue_t* bufferPointer ) 59 | { 60 | if( bufferPointer == &MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1] ) 61 | { 62 | // Reset to the first element 63 | bufferPointer = MlmeConfirmQueue; 64 | } 65 | else 66 | { 67 | // Increase 68 | bufferPointer++; 69 | } 70 | return bufferPointer; 71 | } 72 | 73 | static MlmeConfirmQueue_t* DecreaseBufferPointer( MlmeConfirmQueue_t* bufferPointer ) 74 | { 75 | if( bufferPointer == MlmeConfirmQueue ) 76 | { 77 | // Reset to the last element 78 | bufferPointer = &MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1]; 79 | } 80 | else 81 | { 82 | bufferPointer--; 83 | } 84 | return bufferPointer; 85 | } 86 | 87 | static MlmeConfirmQueue_t* GetElement( Mlme_t request, MlmeConfirmQueue_t* bufferStart, MlmeConfirmQueue_t* bufferEnd ) 88 | { 89 | MlmeConfirmQueue_t* element = bufferStart; 90 | 91 | do 92 | { 93 | if( element->Request == request ) 94 | { 95 | // We have found the element 96 | return element; 97 | } 98 | else 99 | { 100 | element = IncreaseBufferPointer( element ); 101 | } 102 | }while( element != bufferEnd ); 103 | 104 | return NULL; 105 | } 106 | 107 | 108 | void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives ) 109 | { 110 | Primitives = primitives; 111 | 112 | // Init counter 113 | MlmeConfirmQueueCnt = 0; 114 | 115 | // Init buffer 116 | BufferStart = MlmeConfirmQueue; 117 | BufferEnd = MlmeConfirmQueue; 118 | 119 | memset1( (uint8_t*) MlmeConfirmQueue, 0xFF, sizeof( MlmeConfirmQueue ) ); 120 | 121 | // Common status 122 | CommonStatus = LORAMAC_EVENT_INFO_STATUS_ERROR; 123 | } 124 | 125 | bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm ) 126 | { 127 | if( MlmeConfirmQueueCnt >= LORA_MAC_MLME_CONFIRM_QUEUE_LEN ) 128 | { 129 | // Protect the buffer against overwrites 130 | return false; 131 | } 132 | 133 | // Add the element to the ring buffer 134 | BufferEnd->Request = mlmeConfirm->Request; 135 | BufferEnd->Status = mlmeConfirm->Status; 136 | BufferEnd->RestrictCommonReadyToHandle = mlmeConfirm->RestrictCommonReadyToHandle; 137 | BufferEnd->ReadyToHandle = false; 138 | // Increase counter 139 | MlmeConfirmQueueCnt++; 140 | // Update end pointer 141 | BufferEnd = IncreaseBufferPointer( BufferEnd ); 142 | 143 | return true; 144 | } 145 | 146 | bool LoRaMacConfirmQueueRemoveLast( void ) 147 | { 148 | if( MlmeConfirmQueueCnt == 0 ) 149 | { 150 | return false; 151 | } 152 | 153 | // Increase counter 154 | MlmeConfirmQueueCnt--; 155 | // Update start pointer 156 | BufferEnd = DecreaseBufferPointer( BufferEnd ); 157 | 158 | return true; 159 | } 160 | 161 | bool LoRaMacConfirmQueueRemoveFirst( void ) 162 | { 163 | if( MlmeConfirmQueueCnt == 0 ) 164 | { 165 | return false; 166 | } 167 | 168 | // Increase counter 169 | MlmeConfirmQueueCnt--; 170 | // Update start pointer 171 | BufferStart = IncreaseBufferPointer( BufferStart ); 172 | 173 | return true; 174 | } 175 | 176 | void LoRaMacConfirmQueueSetStatus( LoRaMacEventInfoStatus_t status, Mlme_t request ) 177 | { 178 | MlmeConfirmQueue_t* element = NULL; 179 | 180 | if( MlmeConfirmQueueCnt > 0 ) 181 | { 182 | element = GetElement( request, BufferStart, BufferEnd ); 183 | if( element != NULL ) 184 | { 185 | element->Status = status; 186 | element->ReadyToHandle = true; 187 | } 188 | } 189 | } 190 | 191 | LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatus( Mlme_t request ) 192 | { 193 | MlmeConfirmQueue_t* element = NULL; 194 | 195 | if( MlmeConfirmQueueCnt > 0 ) 196 | { 197 | element = GetElement( request, BufferStart, BufferEnd ); 198 | if( element != NULL ) 199 | { 200 | return element->Status; 201 | } 202 | } 203 | return LORAMAC_EVENT_INFO_STATUS_ERROR; 204 | } 205 | 206 | void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status ) 207 | { 208 | MlmeConfirmQueue_t* element = BufferStart; 209 | 210 | CommonStatus = status; 211 | 212 | if( MlmeConfirmQueueCnt > 0 ) 213 | { 214 | do 215 | { 216 | element->Status = status; 217 | // Set the status if it is allowed to set it with a call to 218 | // LoRaMacConfirmQueueSetStatusCmn. 219 | if( element->RestrictCommonReadyToHandle == false ) 220 | { 221 | element->ReadyToHandle = true; 222 | } 223 | element = IncreaseBufferPointer( element ); 224 | }while( element != BufferEnd ); 225 | } 226 | } 227 | 228 | LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatusCmn( void ) 229 | { 230 | return CommonStatus; 231 | } 232 | 233 | bool LoRaMacConfirmQueueIsCmdActive( Mlme_t request ) 234 | { 235 | if( GetElement( request, BufferStart, BufferEnd ) != NULL ) 236 | { 237 | return true; 238 | } 239 | return false; 240 | } 241 | 242 | void LoRaMacConfirmQueueHandleCb( MlmeConfirm_t* mlmeConfirm ) 243 | { 244 | uint8_t nbElements = MlmeConfirmQueueCnt; 245 | bool readyToHandle = false; 246 | MlmeConfirmQueue_t mlmeConfirmToStore; 247 | 248 | for( uint8_t i = 0; i < nbElements; i++ ) 249 | { 250 | mlmeConfirm->MlmeRequest = BufferStart->Request; 251 | mlmeConfirm->Status = BufferStart->Status; 252 | readyToHandle = BufferStart->ReadyToHandle; 253 | 254 | if( readyToHandle == true ) 255 | { 256 | Primitives->MacMlmeConfirm( mlmeConfirm ); 257 | } 258 | else 259 | { 260 | // The request is not processed yet. Store the state. 261 | mlmeConfirmToStore.Request = BufferStart->Request; 262 | mlmeConfirmToStore.Status = BufferStart->Status; 263 | mlmeConfirmToStore.RestrictCommonReadyToHandle = BufferStart->RestrictCommonReadyToHandle; 264 | } 265 | 266 | // Increase the pointer afterwards to prevent overwrites 267 | LoRaMacConfirmQueueRemoveFirst( ); 268 | 269 | if( readyToHandle == false ) 270 | { 271 | // Add a request which has not been finished again to the queue 272 | LoRaMacConfirmQueueAdd( &mlmeConfirmToStore ); 273 | } 274 | } 275 | } 276 | 277 | uint8_t LoRaMacConfirmQueueGetCnt( void ) 278 | { 279 | return MlmeConfirmQueueCnt; 280 | } 281 | 282 | bool LoRaMacConfirmQueueIsFull( void ) 283 | { 284 | if( MlmeConfirmQueueCnt >= LORA_MAC_MLME_CONFIRM_QUEUE_LEN ) 285 | { 286 | return true; 287 | } 288 | else 289 | { 290 | return false; 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /src/LoRaMacConfirmQueue.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file LoRaMacConfirmQueue.h 3 | * 4 | * \brief LoRa MAC confirm queue implementation 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013 Semtech 16 | * 17 | * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 18 | * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 19 | * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 20 | * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 21 | * embedded.connectivity.solutions=============== 22 | * 23 | * \endcode 24 | * 25 | * \author Miguel Luis ( Semtech ) 26 | * 27 | * \author Gregory Cristian ( Semtech ) 28 | * 29 | * \author Daniel Jaeckle ( STACKFORCE ) 30 | * 31 | * \defgroup LORAMACCONFIRMQUEUE LoRa MAC confirm queue implementation 32 | * This module specifies the API implementation of the LoRaMAC confirm queue. 33 | * The confirm queue is implemented with as a ring buffer. The number of 34 | * elements can be defined with \ref LORA_MAC_MLME_CONFIRM_QUEUE_LEN. The 35 | * current implementation does not support multiple elements of the same 36 | * Mlme_t type. 37 | * \{ 38 | */ 39 | #ifndef __LORAMAC_CONFIRMQUEUE_H__ 40 | #define __LORAMAC_CONFIRMQUEUE_H__ 41 | 42 | 43 | /*! 44 | * LoRaMac MLME-Confirm queue length 45 | */ 46 | #define LORA_MAC_MLME_CONFIRM_QUEUE_LEN 5 47 | 48 | /*! 49 | * Structure to hold multiple MLME request confirm data 50 | */ 51 | typedef struct sMlmeConfirmQueue 52 | { 53 | /*! 54 | * Holds the previously performed MLME-Request 55 | */ 56 | Mlme_t Request; 57 | /*! 58 | * Status of the operation 59 | */ 60 | LoRaMacEventInfoStatus_t Status; 61 | /*! 62 | * Set to true, if the request is ready to be handled 63 | */ 64 | bool ReadyToHandle; 65 | /*! 66 | * Set to true, if it is not permitted to set the ReadyToHandle variable 67 | * with a function call to LoRaMacConfirmQueueSetStatusCmn. 68 | */ 69 | bool RestrictCommonReadyToHandle; 70 | }MlmeConfirmQueue_t; 71 | 72 | /*! 73 | * \brief Initializes the confirm queue 74 | * 75 | * \param [IN] primitives - Pointer to the LoRaMac primitives. 76 | */ 77 | void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives ); 78 | 79 | /*! 80 | * \brief Adds an element to the confirm queue. 81 | * 82 | * \param [IN] mlmeConfirm - Pointer to the element to add. 83 | * 84 | * \retval [true - operation was successful, false - operation failed] 85 | */ 86 | bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm ); 87 | 88 | /*! 89 | * \brief Removes the last element which was added into the queue. 90 | * 91 | * \retval [true - operation was successful, false - operation failed] 92 | */ 93 | bool LoRaMacConfirmQueueRemoveLast( void ); 94 | 95 | /*! 96 | * \brief Removes the first element which was added to the confirm queue. 97 | * 98 | * \retval [true - operation was successful, false - operation failed] 99 | */ 100 | bool LoRaMacConfirmQueueRemoveFirst( void ); 101 | 102 | /*! 103 | * \brief Sets the status of an element. 104 | * 105 | * \param [IN] status - The status to set. 106 | * 107 | * \param [IN] request - The related request to set the status. 108 | */ 109 | void LoRaMacConfirmQueueSetStatus( LoRaMacEventInfoStatus_t status, Mlme_t request ); 110 | 111 | /*! 112 | * \brief Gets the status of an element. 113 | * 114 | * \param [IN] request - The request to query the status. 115 | * 116 | * \retval The status of the related MlmeRequest. 117 | */ 118 | LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatus( Mlme_t request ); 119 | 120 | /*! 121 | * \brief Sets a common status for all elements in the queue. 122 | * 123 | * \param [IN] status - The status to set. 124 | */ 125 | void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status ); 126 | 127 | /*! 128 | * \brief Gets the common status of all elements. 129 | * 130 | * \retval The common status of all elements. 131 | */ 132 | LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatusCmn( void ); 133 | 134 | /*! 135 | * \brief Verifies if a request is in the queue and active. 136 | * 137 | * \param [IN] request - The request to verify. 138 | * 139 | * \retval [true - element is in the queue, false - element is not in the queue]. 140 | */ 141 | bool LoRaMacConfirmQueueIsCmdActive( Mlme_t request ); 142 | 143 | /*! 144 | * \brief Handles all callbacks of active requests 145 | * 146 | * \param [IN] mlmeConfirm - Pointer to the generic mlmeConfirm structure. 147 | */ 148 | void LoRaMacConfirmQueueHandleCb( MlmeConfirm_t* mlmeConfirm ); 149 | 150 | /*! 151 | * \brief Query number of elements in the queue. 152 | * 153 | * \retval Number of elements. 154 | */ 155 | uint8_t LoRaMacConfirmQueueGetCnt( void ); 156 | 157 | /*! 158 | * \brief Verify if the confirm queue is full. 159 | * 160 | * \retval [true - queue is full, false - queue is not full]. 161 | */ 162 | bool LoRaMacConfirmQueueIsFull( void ); 163 | 164 | #endif // __LORAMAC_CONFIRMQUEUE_H__ 165 | -------------------------------------------------------------------------------- /src/LoRaMacCrypto.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2017 Alibaba Group Holding Limited 3 | */ 4 | 5 | /* 6 | / _____) _ | | 7 | ( (____ _____ ____ _| |_ _____ ____| |__ 8 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 9 | _____) ) ____| | | || |_| ____( (___| | | | 10 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 11 | (C)2013 Semtech 12 | ___ _____ _ ___ _ _____ ___ ___ ___ ___ 13 | / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 14 | \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 15 | |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 16 | embedded.connectivity.solutions=============== 17 | 18 | Description: LoRa MAC layer implementation 19 | 20 | License: Revised BSD License, see LICENSE.TXT file include in the project 21 | 22 | Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE ) 23 | */ 24 | #include 25 | #include 26 | #include "utilities.h" 27 | 28 | #include "aes.h" 29 | #include "cmac.h" 30 | 31 | #include "LoRaMacCrypto.h" 32 | 33 | /*! 34 | * CMAC/AES Message Integrity Code (MIC) Block B0 size 35 | */ 36 | #define LORAMAC_MIC_BLOCK_B0_SIZE 16 37 | 38 | /*! 39 | * MIC field computation initial data 40 | */ 41 | static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 43 | }; 44 | 45 | /*! 46 | * Contains the computed MIC field. 47 | * 48 | * \remark Only the 4 first bytes are used 49 | */ 50 | static uint8_t Mic[16]; 51 | 52 | /*! 53 | * Encryption aBlock and sBlock 54 | */ 55 | static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 57 | }; 58 | static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 60 | }; 61 | 62 | /*! 63 | * AES computation context variable 64 | */ 65 | static aes_context AesContext; 66 | 67 | /*! 68 | * CMAC computation context variable 69 | */ 70 | static AES_CMAC_CTX AesCmacCtx[1]; 71 | 72 | /*! 73 | * \brief Computes the LoRaMAC frame MIC field 74 | * 75 | * \param [IN] buffer Data buffer 76 | * \param [IN] size Data buffer size 77 | * \param [IN] key AES key to be used 78 | * \param [IN] address Frame address 79 | * \param [IN] dir Frame direction [0: uplink, 1: downlink] 80 | * \param [IN] sequenceCounter Frame sequence counter 81 | * \param [OUT] mic Computed MIC field 82 | */ 83 | void LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic ) 84 | { 85 | MicBlockB0[5] = dir; 86 | 87 | MicBlockB0[6] = ( address ) & 0xFF; 88 | MicBlockB0[7] = ( address >> 8 ) & 0xFF; 89 | MicBlockB0[8] = ( address >> 16 ) & 0xFF; 90 | MicBlockB0[9] = ( address >> 24 ) & 0xFF; 91 | 92 | MicBlockB0[10] = ( sequenceCounter ) & 0xFF; 93 | MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF; 94 | MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF; 95 | MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF; 96 | 97 | MicBlockB0[15] = size & 0xFF; 98 | 99 | AES_CMAC_Init( AesCmacCtx ); 100 | 101 | AES_CMAC_SetKey( AesCmacCtx, key ); 102 | 103 | AES_CMAC_Update( AesCmacCtx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE ); 104 | 105 | AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF ); 106 | 107 | AES_CMAC_Final( Mic, AesCmacCtx ); 108 | 109 | *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] ); 110 | } 111 | 112 | void LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer ) 113 | { 114 | uint16_t i; 115 | uint8_t bufferIndex = 0; 116 | uint16_t ctr = 1; 117 | 118 | memset1( AesContext.ksch, '\0', 240 ); 119 | lorawan_aes_set_key( key, 16, &AesContext ); 120 | 121 | aBlock[5] = dir; 122 | 123 | aBlock[6] = ( address ) & 0xFF; 124 | aBlock[7] = ( address >> 8 ) & 0xFF; 125 | aBlock[8] = ( address >> 16 ) & 0xFF; 126 | aBlock[9] = ( address >> 24 ) & 0xFF; 127 | 128 | aBlock[10] = ( sequenceCounter ) & 0xFF; 129 | aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF; 130 | aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF; 131 | aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF; 132 | 133 | while( size >= 16 ) 134 | { 135 | aBlock[15] = ( ( ctr ) & 0xFF ); 136 | ctr++; 137 | lora_aes_encrypt( aBlock, sBlock, &AesContext ); 138 | for( i = 0; i < 16; i++ ) 139 | { 140 | encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]; 141 | } 142 | size -= 16; 143 | bufferIndex += 16; 144 | } 145 | 146 | if( size > 0 ) 147 | { 148 | aBlock[15] = ( ( ctr ) & 0xFF ); 149 | lora_aes_encrypt( aBlock, sBlock, &AesContext ); 150 | for( i = 0; i < size; i++ ) 151 | { 152 | encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]; 153 | } 154 | } 155 | } 156 | 157 | void LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer ) 158 | { 159 | LoRaMacPayloadEncrypt( buffer, size, key, address, dir, sequenceCounter, decBuffer ); 160 | } 161 | 162 | void LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic ) 163 | { 164 | AES_CMAC_Init( AesCmacCtx ); 165 | 166 | AES_CMAC_SetKey( AesCmacCtx, key ); 167 | 168 | AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF ); 169 | 170 | AES_CMAC_Final( Mic, AesCmacCtx ); 171 | 172 | *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] ); 173 | } 174 | 175 | void LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer ) 176 | { 177 | memset1( AesContext.ksch, '\0', 240 ); 178 | lorawan_aes_set_key( key, 16, &AesContext ); 179 | lora_aes_encrypt( buffer, decBuffer, &AesContext ); 180 | // Check if optional CFList is included 181 | if( size >= 16 ) 182 | { 183 | lora_aes_encrypt( buffer + 16, decBuffer + 16, &AesContext ); 184 | } 185 | } 186 | 187 | void LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey ) 188 | { 189 | uint8_t nonce[16]; 190 | uint8_t *pDevNonce = ( uint8_t * )&devNonce; 191 | 192 | memset1( AesContext.ksch, '\0', 240 ); 193 | lorawan_aes_set_key( key, 16, &AesContext ); 194 | 195 | memset1( nonce, 0, sizeof( nonce ) ); 196 | nonce[0] = 0x01; 197 | memcpy1( nonce + 1, appNonce, 6 ); 198 | memcpy1( nonce + 7, pDevNonce, 2 ); 199 | lora_aes_encrypt( nonce, nwkSKey, &AesContext ); 200 | 201 | memset1( nonce, 0, sizeof( nonce ) ); 202 | nonce[0] = 0x02; 203 | memcpy1( nonce + 1, appNonce, 6 ); 204 | memcpy1( nonce + 7, pDevNonce, 2 ); 205 | lora_aes_encrypt( nonce, appSKey, &AesContext ); 206 | } 207 | 208 | void LoRaMacBeaconComputePingOffset( uint64_t beaconTime, uint32_t address, uint16_t pingPeriod, uint16_t *pingOffset ) 209 | { 210 | uint8_t zeroKey[16]; 211 | uint8_t buffer[16]; 212 | uint8_t cipher[16]; 213 | uint32_t result = 0; 214 | /* Refer to chapter 15.2 of the LoRaWAN specification v1.1. The beacon time 215 | * GPS time in seconds modulo 2^32 216 | */ 217 | uint32_t time = ( beaconTime % ( ( ( uint64_t ) 1 ) << 32 ) ); 218 | 219 | memset1( zeroKey, 0, 16 ); 220 | memset1( buffer, 0, 16 ); 221 | memset1( cipher, 0, 16 ); 222 | memset1( AesContext.ksch, '\0', 240 ); 223 | 224 | buffer[0] = ( time ) & 0xFF; 225 | buffer[1] = ( time >> 8 ) & 0xFF; 226 | buffer[2] = ( time >> 16 ) & 0xFF; 227 | buffer[3] = ( time >> 24 ) & 0xFF; 228 | 229 | buffer[4] = ( address ) & 0xFF; 230 | buffer[5] = ( address >> 8 ) & 0xFF; 231 | buffer[6] = ( address >> 16 ) & 0xFF; 232 | buffer[7] = ( address >> 24 ) & 0xFF; 233 | 234 | lorawan_aes_set_key( zeroKey, 16, &AesContext ); 235 | lora_aes_encrypt( buffer, cipher, &AesContext ); 236 | 237 | result = ( ( ( uint32_t ) cipher[0] ) + ( ( ( uint32_t ) cipher[1] ) * 256 ) ); 238 | 239 | *pingOffset = ( uint16_t )( result % pingPeriod ); 240 | } 241 | -------------------------------------------------------------------------------- /src/LoRaMacCrypto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2017 Alibaba Group Holding Limited 3 | */ 4 | 5 | /*! 6 | * \file LoRaMacCrypto.h 7 | * 8 | * \brief LoRa MAC layer cryptography implementation 9 | * 10 | * \copyright Revised BSD License, see section \ref LICENSE. 11 | * 12 | * \code 13 | * ______ _ 14 | * / _____) _ | | 15 | * ( (____ _____ ____ _| |_ _____ ____| |__ 16 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 17 | * _____) ) ____| | | || |_| ____( (___| | | | 18 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 19 | * (C)2013 Semtech 20 | * 21 | * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 22 | * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 23 | * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 24 | * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 25 | * embedded.connectivity.solutions=============== 26 | * 27 | * \endcode 28 | * 29 | * \author Miguel Luis ( Semtech ) 30 | * 31 | * \author Gregory Cristian ( Semtech ) 32 | * 33 | * \author Daniel Jaeckle ( STACKFORCE ) 34 | * 35 | * \defgroup LORAMAC_CRYPTO LoRa MAC layer cryptography implementation 36 | * This module covers the implementation of cryptographic functions 37 | * of the LoRaMAC layer. 38 | * \{ 39 | */ 40 | #ifndef __LORAMAC_CRYPTO_H__ 41 | #define __LORAMAC_CRYPTO_H__ 42 | 43 | /*! 44 | * Computes the LoRaMAC frame MIC field 45 | * 46 | * \param [IN] buffer - Data buffer 47 | * \param [IN] size - Data buffer size 48 | * \param [IN] key - AES key to be used 49 | * \param [IN] address - Frame address 50 | * \param [IN] dir - Frame direction [0: uplink, 1: downlink] 51 | * \param [IN] sequenceCounter - Frame sequence counter 52 | * \param [OUT] mic - Computed MIC field 53 | */ 54 | void LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic ); 55 | 56 | /*! 57 | * Computes the LoRaMAC payload encryption 58 | * 59 | * \param [IN] buffer - Data buffer 60 | * \param [IN] size - Data buffer size 61 | * \param [IN] key - AES key to be used 62 | * \param [IN] address - Frame address 63 | * \param [IN] dir - Frame direction [0: uplink, 1: downlink] 64 | * \param [IN] sequenceCounter - Frame sequence counter 65 | * \param [OUT] encBuffer - Encrypted buffer 66 | */ 67 | void LoRaMacPayloadEncrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer ); 68 | 69 | /*! 70 | * Computes the LoRaMAC payload decryption 71 | * 72 | * \param [IN] buffer - Data buffer 73 | * \param [IN] size - Data buffer size 74 | * \param [IN] key - AES key to be used 75 | * \param [IN] address - Frame address 76 | * \param [IN] dir - Frame direction [0: uplink, 1: downlink] 77 | * \param [IN] sequenceCounter - Frame sequence counter 78 | * \param [OUT] decBuffer - Decrypted buffer 79 | */ 80 | void LoRaMacPayloadDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer ); 81 | 82 | /*! 83 | * Computes the LoRaMAC Join Request frame MIC field 84 | * 85 | * \param [IN] buffer - Data buffer 86 | * \param [IN] size - Data buffer size 87 | * \param [IN] key - AES key to be used 88 | * \param [OUT] mic - Computed MIC field 89 | */ 90 | void LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic ); 91 | 92 | /*! 93 | * Computes the LoRaMAC join frame decryption 94 | * 95 | * \param [IN] buffer - Data buffer 96 | * \param [IN] size - Data buffer size 97 | * \param [IN] key - AES key to be used 98 | * \param [OUT] decBuffer - Decrypted buffer 99 | */ 100 | void LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer ); 101 | 102 | /*! 103 | * Computes the LoRaMAC join frame decryption 104 | * 105 | * \param [IN] key - AES key to be used 106 | * \param [IN] appNonce - Application nonce 107 | * \param [IN] devNonce - Device nonce 108 | * \param [OUT] nwkSKey - Network session key 109 | * \param [OUT] appSKey - Application session key 110 | */ 111 | void LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey ); 112 | 113 | /*! 114 | * Computes the LoRaMAC join frame decryption 115 | * 116 | * \param [IN] beaconTime - Time of the recent received beacon 117 | * \param [IN] address - Frame address 118 | * \param [IN] pingPeriod - Ping period of the node 119 | * \param [OUT] pingOffset - Pseudo random ping offset 120 | */ 121 | void LoRaMacBeaconComputePingOffset( uint64_t beaconTime, uint32_t address, uint16_t pingPeriod, uint16_t *pingOffset ); 122 | 123 | /*! \} defgroup LORAMAC */ 124 | 125 | #endif // __LORAMAC_CRYPTO_H__ 126 | -------------------------------------------------------------------------------- /src/LoRaMacTest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2017 Alibaba Group Holding Limited 3 | */ 4 | 5 | /*! 6 | * \file LoRaMacTest.h 7 | * 8 | * \brief LoRa MAC layer test function implementation 9 | * 10 | * \copyright Revised BSD License, see section \ref LICENSE. 11 | * 12 | * \code 13 | * ______ _ 14 | * / _____) _ | | 15 | * ( (____ _____ ____ _| |_ _____ ____| |__ 16 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 17 | * _____) ) ____| | | || |_| ____( (___| | | | 18 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 19 | * (C)2013 Semtech 20 | * 21 | * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 22 | * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 23 | * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 24 | * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 25 | * embedded.connectivity.solutions=============== 26 | * 27 | * \endcode 28 | * 29 | * \author Miguel Luis ( Semtech ) 30 | * 31 | * \author Gregory Cristian ( Semtech ) 32 | * 33 | * \author Daniel Jaeckle ( STACKFORCE ) 34 | * 35 | * \defgroup LORAMACTEST LoRa MAC layer test function implementation 36 | * This module specifies the API implementation of test function of the LoRaMAC layer. 37 | * The functions in this file are only for testing purposes only. 38 | * \{ 39 | */ 40 | #ifndef __LORAMACTEST_H__ 41 | #define __LORAMACTEST_H__ 42 | 43 | /*! 44 | * \brief Enabled or disables the reception windows 45 | * 46 | * \details This is a test function. It shall be used for testing purposes only. 47 | * Changing this attribute may lead to a non-conformance LoRaMac operation. 48 | * 49 | * \param [IN] enable - Enabled or disables the reception windows 50 | */ 51 | void LoRaMacTestRxWindowsOn( bool enable ); 52 | 53 | /*! 54 | * \brief Enables the MIC field test 55 | * 56 | * \details This is a test function. It shall be used for testing purposes only. 57 | * Changing this attribute may lead to a non-conformance LoRaMac operation. 58 | * 59 | * \param [IN] txPacketCounter - Fixed Tx packet counter value 60 | */ 61 | void LoRaMacTestSetMic( uint16_t txPacketCounter ); 62 | 63 | /*! 64 | * \brief Enabled or disables the duty cycle 65 | * 66 | * \details This is a test function. It shall be used for testing purposes only. 67 | * Changing this attribute may lead to a non-conformance LoRaMac operation. 68 | * 69 | * \param [IN] enable - Enabled or disables the duty cycle 70 | */ 71 | void LoRaMacTestSetDutyCycleOn( bool enable ); 72 | 73 | /*! 74 | * \brief Sets the channel index 75 | * 76 | * \details This is a test function. It shall be used for testing purposes only. 77 | * Changing this attribute may lead to a non-conformance LoRaMac operation. 78 | * 79 | * \param [IN] channel - Channel index 80 | */ 81 | void LoRaMacTestSetChannel( uint8_t channel ); 82 | 83 | /*! \} defgroup LORAMACTEST */ 84 | 85 | #endif // __LORAMACTEST_H__ 86 | -------------------------------------------------------------------------------- /src/Mcu.h: -------------------------------------------------------------------------------- 1 | #ifndef McuSet_H 2 | #define McuSet_H 3 | 4 | #include 5 | #include "SPI.h" 6 | #include "soc/rtc.h" 7 | #include "soc/rtc_cntl_reg.h" 8 | #include "driver/rtc_io.h" 9 | #include "driver/rtc_io.h" 10 | #include "timer.h" 11 | #include "rtc-board.h" 12 | #include "board-config.h" 13 | //#include "LoRaMac.h" 14 | #include "esp_spi_flash.h" 15 | #include "esp_partition.h" 16 | 17 | #define LORA_DEFAULT_NSS_PIN 18 18 | #define LORA_DEFAULT_RESET_PIN 14 19 | #define LORA_DEFAULT_DIO0_PIN 26 20 | #define LORA_DEFAULT_DIO1_PIN 33 21 | #define Timer_DEFAULT_DIV 80 22 | extern uint8_t mcuStarted; 23 | class McuClass{ 24 | public: 25 | McuClass(); 26 | void calrtc(); 27 | void init(int nss, int reset, int dio0, int dio1,uint32_t * codeid); 28 | void setSPIFrequency(uint32_t frequency); 29 | void sleep(uint8_t CLASS,uint8_t debuglevel); 30 | void setTimerDiv(uint16_t div); 31 | uint8_t readRegister(uint16_t address); 32 | void writeRegister(uint16_t address, uint8_t value); 33 | uint8_t singleTransfer(uint16_t address, uint8_t value); 34 | void writefifo0(uint16_t address, uint8_t *buffer, uint8_t size); 35 | void readfifo0(uint16_t address, uint8_t *buffer, uint8_t size); 36 | 37 | private: 38 | SPISettings _spiSettings; 39 | int _nss; 40 | int _reset; 41 | int _dio0; 42 | int _dio1; 43 | uint16_t _div; 44 | }; 45 | extern TimerEvent_t TxNextPacketTimer; 46 | 47 | extern bool factory_test; 48 | #ifdef __cplusplus 49 | extern "C" void write0(uint16_t address, uint8_t value); 50 | extern "C" uint8_t read0(uint16_t address); 51 | extern "C" void lora_printf(const char *format, ...); 52 | extern "C" void writefifo(uint16_t address, uint8_t *buffer, uint8_t size); 53 | extern "C" void readfifo(uint16_t address, uint8_t *buffer, uint8_t size); 54 | extern "C" uint64_t timercheck(); 55 | extern "C" void calRTC(); 56 | extern "C" size_t getLicenseAddress(); 57 | #endif 58 | 59 | extern McuClass Mcu; 60 | #endif 61 | -------------------------------------------------------------------------------- /src/OLEDDisplay.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelTecAutomation/ESP32_LoRaWAN/7b5d52b4666c90b9aa0dfa15189678d2d7e12b54/src/OLEDDisplay.cpp -------------------------------------------------------------------------------- /src/RTE_Components.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Auto generated Run-Time-Environment Component Configuration File 4 | * *** Do not modify ! *** 5 | * 6 | * Project: 'LoRaWAN' 7 | * Target: 'LoRaWAN Configuration' 8 | */ 9 | 10 | #ifndef RTE_COMPONENTS_H 11 | #define RTE_COMPONENTS_H 12 | 13 | 14 | #endif /* RTE_COMPONENTS_H */ 15 | -------------------------------------------------------------------------------- /src/SSD1306.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SSD1306_h 32 | #define SSD1306_h 33 | #include "SSD1306Wire.h" 34 | 35 | // For legacy support make SSD1306 an alias for SSD1306 36 | typedef SSD1306Wire SSD1306; 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/SSD1306Wire.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2018 by ThingPulse, Daniel Eichhorn 5 | * Copyright (c) 2018 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | * ThingPulse invests considerable time and money to develop these open source libraries. 26 | * Please support us by buying our products (and not the clones) from 27 | * https://thingpulse.com 28 | * 29 | */ 30 | 31 | #ifndef SSD1306Wire_h 32 | #define SSD1306Wire_h 33 | 34 | #include "OLEDDisplay.h" 35 | #include 36 | 37 | 38 | class SSD1306Wire : public OLEDDisplay { 39 | private: 40 | uint8_t _address; 41 | uint8_t _sda; 42 | uint8_t _scl; 43 | uint8_t _rst; 44 | bool _doI2cAutoInit = false; 45 | 46 | public: 47 | SSD1306Wire(uint8_t _address, uint8_t _sda, uint8_t _scl, uint8_t _rst, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) { 48 | setGeometry(g); 49 | 50 | this->_address = _address; 51 | this->_sda = _sda; 52 | this->_scl = _scl; 53 | this->_rst = _rst; 54 | } 55 | 56 | 57 | bool connect() { 58 | pinMode(_rst,OUTPUT); 59 | digitalWrite(_rst, LOW); 60 | delay(50); 61 | digitalWrite(_rst, HIGH); 62 | 63 | Wire.begin(this->_sda, this->_scl); 64 | // Let's use ~700khz if ESP8266 is in 160Mhz mode 65 | // this will be limited to ~400khz if the ESP8266 in 80Mhz mode. 66 | Wire.setClock(700000); 67 | return true; 68 | } 69 | 70 | void display(void) { 71 | initI2cIfNeccesary(); 72 | if(rotate_angle==ANGLE_0_DEGREE||rotate_angle==ANGLE_180_DEGREE) 73 | { 74 | const int x_offset = (128 - this->width()) / 2; 75 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 76 | uint8_t minBoundY = UINT8_MAX; 77 | uint8_t maxBoundY = 0; 78 | 79 | uint8_t minBoundX = UINT8_MAX; 80 | uint8_t maxBoundX = 0; 81 | uint8_t x, y; 82 | 83 | // Calculate the Y bounding box of changes 84 | // and copy buffer[pos] to buffer_back[pos]; 85 | for (y = 0; y < (this->height() / 8); y++) 86 | { 87 | for (x = 0; x < this->width(); x++) 88 | { 89 | uint16_t pos = x + y * this->width(); 90 | if (buffer[pos] != buffer_back[pos]) 91 | { 92 | minBoundY = _min(minBoundY, y); 93 | maxBoundY = _max(maxBoundY, y); 94 | minBoundX = _min(minBoundX, x); 95 | maxBoundX = _max(maxBoundX, x); 96 | } 97 | buffer_back[pos] = buffer[pos]; 98 | } 99 | //yield(); 100 | } 101 | 102 | // If the minBoundY wasn't updated 103 | // we can savely assume that buffer_back[pos] == buffer[pos] 104 | // holdes true for all values of pos 105 | 106 | if (minBoundY == UINT8_MAX) return; 107 | 108 | sendCommand(COLUMNADDR); 109 | sendCommand(x_offset+minBoundX); 110 | sendCommand(x_offset+ maxBoundX); 111 | 112 | sendCommand(PAGEADDR); 113 | sendCommand(minBoundY); 114 | sendCommand(maxBoundY); 115 | 116 | byte k = 0; 117 | for (y = minBoundY; y <= maxBoundY; y++) 118 | { 119 | for (x = minBoundX; x <= maxBoundX; x++) 120 | { 121 | if (k == 0) 122 | { 123 | Wire.beginTransmission(_address); 124 | Wire.write(0x40); 125 | } 126 | 127 | Wire.write(buffer[x + y * this->width()]); 128 | k++; 129 | if (k == 16) 130 | { 131 | Wire.endTransmission(); 132 | k = 0; 133 | } 134 | } 135 | //yield(); 136 | } 137 | 138 | if (k != 0) { 139 | Wire.endTransmission(); 140 | } 141 | #else 142 | 143 | sendCommand(COLUMNADDR); 144 | sendCommand(x_offset); 145 | sendCommand(x_offset+(this->width() - 1)); 146 | 147 | sendCommand(PAGEADDR); 148 | sendCommand(0x0); 149 | sendCommand((this->height() / 8) - 1); 150 | 151 | if (geometry == GEOMETRY_128_64) 152 | { 153 | sendCommand(0x7); 154 | } 155 | else if (geometry == GEOMETRY_128_32) 156 | { 157 | sendCommand(0x3); 158 | } 159 | 160 | for (uint16_t i=0; i < displayBufferSize; i++) 161 | { 162 | Wire.beginTransmission(this->_address); 163 | Wire.write(0x40); 164 | for (uint8_t x = 0; x < 16; x++) 165 | { 166 | Wire.write(buffer[i]); 167 | i++; 168 | } 169 | i--; 170 | Wire.endTransmission(); 171 | } 172 | #endif 173 | } 174 | else 175 | { 176 | uint8_t buffer_rotate[displayBufferSize]; 177 | memset(buffer_rotate,0,displayBufferSize); 178 | uint8_t temp; 179 | for(uint16_t i=0;iwidth();i++) 180 | { 181 | for(uint16_t j=0;jheight();j++) 182 | { 183 | temp = buffer[(j>>3)*this->width()+i]>>(j&7)&0x01; 184 | buffer_rotate[(i>>3)*this->height()+j]|=(temp<<(i&7)); 185 | } 186 | } 187 | #ifdef OLEDDISPLAY_DOUBLE_BUFFER 188 | uint8_t minBoundY = UINT8_MAX; 189 | uint8_t maxBoundY = 0; 190 | 191 | uint8_t minBoundX = UINT8_MAX; 192 | uint8_t maxBoundX = 0; 193 | uint8_t x, y; 194 | const int x_offset = (128 - this->height()) / 2; 195 | // Calculate the Y bounding box of changes 196 | // and copy buffer[pos] to buffer_back[pos]; 197 | for (y = 0; y < (this->width() / 8); y++) 198 | { 199 | for (x = 0; x < this->height(); x++) 200 | { 201 | uint16_t pos = x + y * this->height(); 202 | if (buffer_rotate[pos] != buffer_back[pos]) 203 | { 204 | minBoundY = _min(minBoundY, y); 205 | maxBoundY = _max(maxBoundY, y); 206 | minBoundX = _min(minBoundX, x); 207 | maxBoundX = _max(maxBoundX, x); 208 | } 209 | buffer_back[pos] = buffer_rotate[pos]; 210 | } 211 | //yield(); 212 | } 213 | if (minBoundY == UINT8_MAX) return; 214 | 215 | sendCommand(COLUMNADDR); 216 | sendCommand(x_offset+minBoundX); 217 | sendCommand(x_offset+maxBoundX); 218 | 219 | sendCommand(PAGEADDR); 220 | sendCommand(minBoundY); 221 | sendCommand(maxBoundY); 222 | 223 | byte k = 0; 224 | for (y = minBoundY; y <= maxBoundY; y++) 225 | { 226 | for (x = minBoundX; x <= maxBoundX; x++) 227 | { 228 | if (k == 0) 229 | { 230 | Wire.beginTransmission(_address); 231 | Wire.write(0x40); 232 | } 233 | 234 | Wire.write(buffer_rotate[x + y * this->height()]); 235 | k++; 236 | if (k == 16) 237 | { 238 | Wire.endTransmission(); 239 | k = 0; 240 | } 241 | } 242 | //yield(); 243 | } 244 | 245 | if (k != 0) { 246 | Wire.endTransmission(); 247 | } 248 | #else 249 | sendCommand(COLUMNADDR); 250 | sendCommand(x_offset); 251 | sendCommand(x_offset+(this->height() - 1)); 252 | 253 | sendCommand(PAGEADDR); 254 | sendCommand(0x0); 255 | sendCommand((this->width() / 8) - 1); 256 | 257 | if (geometry == GEOMETRY_128_64) 258 | { 259 | sendCommand(0x7); 260 | } 261 | else if (geometry == GEOMETRY_128_32) 262 | { 263 | sendCommand(0x3); 264 | } 265 | 266 | for (uint16_t i=0; i < displayBufferSize; i++) 267 | { 268 | Wire.beginTransmission(this->_address); 269 | Wire.write(0x40); 270 | for (uint8_t x = 0; x < 16; x++) 271 | { 272 | Wire.write(buffer_rotate[i]); 273 | i++; 274 | } 275 | i--; 276 | Wire.endTransmission(); 277 | } 278 | #endif 279 | } 280 | } 281 | 282 | void setI2cAutoInit(bool doI2cAutoInit) { 283 | _doI2cAutoInit = doI2cAutoInit; 284 | } 285 | 286 | private: 287 | int getBufferOffset(void) { 288 | return 0; 289 | } 290 | inline void sendCommand(uint8_t command) __attribute__((always_inline)){ 291 | initI2cIfNeccesary(); 292 | Wire.beginTransmission(_address); 293 | Wire.write(0x80); 294 | Wire.write(command); 295 | Wire.endTransmission(); 296 | } 297 | 298 | void initI2cIfNeccesary() { 299 | if (_doI2cAutoInit) { 300 | Wire.begin(this->_sda, this->_scl); 301 | } 302 | } 303 | 304 | }; 305 | 306 | #endif 307 | -------------------------------------------------------------------------------- /src/aes.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The redistribution and use of this software (with or without changes) 8 | is allowed without the payment of fees or royalties provided that: 9 | 10 | 1. source code distributions include the above copyright notice, this 11 | list of conditions and the following disclaimer; 12 | 13 | 2. binary distributions include the above copyright notice, this list 14 | of conditions and the following disclaimer in their documentation; 15 | 16 | 3. the name of the copyright holder is not used to endorse products 17 | built using this software without specific written permission. 18 | 19 | DISCLAIMER 20 | 21 | This software is provided 'as is' with no explicit or implied warranties 22 | in respect of its properties, including, but not limited to, correctness 23 | and/or fitness for purpose. 24 | --------------------------------------------------------------------------- 25 | Issue 09/09/2006 26 | 27 | This is an AES implementation that uses only 8-bit byte operations on the 28 | cipher state. 29 | */ 30 | 31 | #ifndef AES_H 32 | #define AES_H 33 | 34 | #if 1 35 | # define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */ 36 | #endif 37 | #if 0 38 | # define AES_DEC_PREKEYED /* AES decryption with a precomputed key schedule */ 39 | #endif 40 | #if 0 41 | # define AES_ENC_128_OTFK /* AES encryption with 'on the fly' 128 bit keying */ 42 | #endif 43 | #if 0 44 | # define AES_DEC_128_OTFK /* AES decryption with 'on the fly' 128 bit keying */ 45 | #endif 46 | #if 0 47 | # define AES_ENC_256_OTFK /* AES encryption with 'on the fly' 256 bit keying */ 48 | #endif 49 | #if 0 50 | # define AES_DEC_256_OTFK /* AES decryption with 'on the fly' 256 bit keying */ 51 | #endif 52 | 53 | #define N_ROW 4 54 | #define N_COL 4 55 | #define N_BLOCK (N_ROW * N_COL) 56 | #define N_MAX_ROUNDS 14 57 | 58 | typedef uint8_t return_type; 59 | 60 | /* Warning: The key length for 256 bit keys overflows a byte 61 | (see comment below) 62 | */ 63 | 64 | typedef uint8_t length_type; 65 | 66 | typedef struct 67 | { uint8_t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK]; 68 | uint8_t rnd; 69 | } aes_context; 70 | 71 | /* The following calls are for a precomputed key schedule 72 | 73 | NOTE: If the length_type used for the key length is an 74 | unsigned 8-bit character, a key length of 256 bits must 75 | be entered as a length in bytes (valid inputs are hence 76 | 128, 192, 16, 24 and 32). 77 | */ 78 | 79 | #if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED ) 80 | 81 | return_type lorawan_aes_set_key( const uint8_t key[], 82 | length_type keylen, 83 | aes_context ctx[1] ); 84 | #endif 85 | 86 | #if defined( AES_ENC_PREKEYED ) 87 | 88 | return_type lora_aes_encrypt( const uint8_t in[N_BLOCK], 89 | uint8_t out[N_BLOCK], 90 | const aes_context ctx[1] ); 91 | 92 | return_type lorawan_aes_cbc_encrypt( const uint8_t *in, 93 | uint8_t *out, 94 | int32_t n_block, 95 | uint8_t iv[N_BLOCK], 96 | const aes_context ctx[1] ); 97 | #endif 98 | 99 | #if defined( AES_DEC_PREKEYED ) 100 | 101 | return_type aes_decrypt( const uint8_t in[N_BLOCK], 102 | uint8_t out[N_BLOCK], 103 | const aes_context ctx[1] ); 104 | 105 | return_type aes_cbc_decrypt( const uint8_t *in, 106 | uint8_t *out, 107 | int32_t n_block, 108 | uint8_t iv[N_BLOCK], 109 | const aes_context ctx[1] ); 110 | #endif 111 | 112 | /* The following calls are for 'on the fly' keying. In this case the 113 | encryption and decryption keys are different. 114 | 115 | The encryption subroutines take a key in an array of bytes in 116 | key[L] where L is 16, 24 or 32 bytes for key lengths of 128, 117 | 192, and 256 bits respectively. They then encrypts the input 118 | data, in[] with this key and put the reult in the output array 119 | out[]. In addition, the second key array, o_key[L], is used 120 | to output the key that is needed by the decryption subroutine 121 | to reverse the encryption operation. The two key arrays can 122 | be the same array but in this case the original key will be 123 | overwritten. 124 | 125 | In the same way, the decryption subroutines output keys that 126 | can be used to reverse their effect when used for encryption. 127 | 128 | Only 128 and 256 bit keys are supported in these 'on the fly' 129 | modes. 130 | */ 131 | 132 | #if defined( AES_ENC_128_OTFK ) 133 | void aes_encrypt_128( const uint8_t in[N_BLOCK], 134 | uint8_t out[N_BLOCK], 135 | const uint8_t key[N_BLOCK], 136 | uint8_t o_key[N_BLOCK] ); 137 | #endif 138 | 139 | #if defined( AES_DEC_128_OTFK ) 140 | void aes_decrypt_128( const uint8_t in[N_BLOCK], 141 | uint8_t out[N_BLOCK], 142 | const uint8_t key[N_BLOCK], 143 | uint8_t o_key[N_BLOCK] ); 144 | #endif 145 | 146 | #if defined( AES_ENC_256_OTFK ) 147 | void aes_encrypt_256( const uint8_t in[N_BLOCK], 148 | uint8_t out[N_BLOCK], 149 | const uint8_t key[2 * N_BLOCK], 150 | uint8_t o_key[2 * N_BLOCK] ); 151 | #endif 152 | 153 | #if defined( AES_DEC_256_OTFK ) 154 | void aes_decrypt_256( const uint8_t in[N_BLOCK], 155 | uint8_t out[N_BLOCK], 156 | const uint8_t key[2 * N_BLOCK], 157 | uint8_t o_key[2 * N_BLOCK] ); 158 | #endif 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /src/board-config.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file board-config.h 3 | * 4 | * \brief Board configuration 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013-2017 Semtech 16 | * 17 | * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 18 | * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 19 | * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 20 | * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 21 | * embedded.connectivity.solutions=============== 22 | * 23 | * \endcode 24 | * 25 | * \author Miguel Luis ( Semtech ) 26 | * 27 | * \author Gregory Cristian ( Semtech ) 28 | * 29 | * \author Daniel Jaeckle ( STACKFORCE ) 30 | * 31 | * \author Johannes Bruder ( STACKFORCE ) 32 | */ 33 | #ifndef __BOARD_CONFIG_H__ 34 | #define __BOARD_CONFIG_H__ 35 | 36 | /*! 37 | * Defines the time required for the TCXO to wakeup [ms]. 38 | */ 39 | 40 | #define BOARD_TCXO_WAKEUP_TIME 0 41 | 42 | 43 | /*! 44 | * Board MCU pins definitions 45 | */ 46 | #define RADIO_RESET 14 47 | 48 | #define RADIO_MOSI 27 49 | #define RADIO_MISO 19 50 | #define RADIO_SCLK 5 51 | #define RADIO_NSS 18 52 | 53 | #define RADIO_DIO_0 26 54 | 55 | #define V2 56 | #ifdef V2 //WIFI Kit series V1 not support Vext control 57 | #define RADIO_DIO_1 35 // GPIO35 -- SX127x's IRQ(Interrupt Request) V2 58 | #else 59 | #define RADIO_DIO_1 33 // GPIO33 -- SX127x's IRQ(Interrupt Request) V1 60 | #endif 61 | 62 | //#define Vext 21 63 | 64 | 65 | 66 | #endif // __BOARD_CONFIG_H__ 67 | -------------------------------------------------------------------------------- /src/board.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelTecAutomation/ESP32_LoRaWAN/7b5d52b4666c90b9aa0dfa15189678d2d7e12b54/src/board.c -------------------------------------------------------------------------------- /src/board.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file board.h 3 | * 4 | * \brief Target board general functions implementation 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013-2017 Semtech 16 | * 17 | * \endcode 18 | * 19 | * \author Miguel Luis ( Semtech ) 20 | * 21 | * \author Gregory Cristian ( Semtech ) 22 | */ 23 | #ifndef __BOARD_H__ 24 | #define __BOARD_H__ 25 | 26 | #include 27 | #include "timer.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C"{ 31 | #endif 32 | 33 | /*! 34 | * Possible power sources 35 | */ 36 | enum BoardPowerSources 37 | { 38 | USB_POWER = 0, 39 | BATTERY_POWER, 40 | }; 41 | 42 | /*! 43 | * Board Version 44 | */ 45 | typedef union BoardVersion_u 46 | { 47 | struct BoardVersion_s 48 | { 49 | uint8_t Rfu; 50 | uint8_t Revision; 51 | uint8_t Minor; 52 | uint8_t Major; 53 | }Fields; 54 | uint32_t Value; 55 | }BoardVersion_t; 56 | 57 | /*! 58 | * \brief Disable interrupts 59 | * 60 | * \remark IRQ nesting is managed 61 | */ 62 | void BoardDisableIrq( void ); 63 | 64 | /*! 65 | * \brief Enable interrupts 66 | * 67 | * \remark IRQ nesting is managed 68 | */ 69 | void BoardEnableIrq( void ); 70 | 71 | /*! 72 | * \brief Initializes the mcu. 73 | */ 74 | void BoardInitMcu( void ); 75 | 76 | /*! 77 | * \brief Resets the mcu. 78 | */ 79 | void BoardResetMcu( void ); 80 | 81 | /*! 82 | * \brief Initializes the boards peripherals. 83 | */ 84 | void BoardInitPeriph( void ); 85 | 86 | /*! 87 | * \brief De-initializes the target board peripherals to decrease power 88 | * consumption. 89 | */ 90 | void BoardDeInitMcu( void ); 91 | 92 | /*! 93 | * \brief Gets the current potentiometer level value 94 | * 95 | * \retval value Potentiometer level ( value in percent ) 96 | */ 97 | uint8_t BoardGetPotiLevel( void ); 98 | 99 | /*! 100 | * \brief Measure the Battery voltage 101 | * 102 | * \retval value battery voltage in volts 103 | */ 104 | uint32_t BoardGetBatteryVoltage( void ); 105 | 106 | /*! 107 | * \brief Get the current battery level 108 | * 109 | * \retval value battery level [ 0: USB, 110 | * 1: Min level, 111 | * x: level 112 | * 254: fully charged, 113 | * 255: Error] 114 | */ 115 | uint8_t BoardGetBatteryLevel( void ); 116 | 117 | /*! 118 | * Returns a pseudo random seed generated using the MCU Unique ID 119 | * 120 | * \retval seed Generated pseudo random seed 121 | */ 122 | uint32_t BoardGetRandomSeed( void ); 123 | 124 | /*! 125 | * \brief Gets the board 64 bits unique ID 126 | * 127 | * \param [IN] id Pointer to an array that will contain the Unique ID 128 | */ 129 | void BoardGetUniqueId( uint8_t *id ); 130 | 131 | /*! 132 | * \brief Get the board power source 133 | * 134 | * \retval value power source [0: USB_POWER, 1: BATTERY_POWER] 135 | */ 136 | uint8_t GetBoardPowerSource( void ); 137 | 138 | /*! 139 | * \brief Get the board version 140 | * 141 | * \retval value Version 142 | */ 143 | BoardVersion_t BoardGetVersion( void ); 144 | 145 | 146 | #ifdef __cplusplus 147 | } // extern "C" 148 | #endif 149 | 150 | #endif // __BOARD_H__ 151 | -------------------------------------------------------------------------------- /src/cmac.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | Copyright (C) 2009 Lander Casado, Philippas Tsigas 3 | 4 | All rights reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files 8 | (the "Software"), to deal with the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | Redistributions of source code must retain the above copyright notice, 15 | this list of conditions and the following disclaimers. Redistributions in 16 | binary form must reproduce the above copyright notice, this list of 17 | conditions and the following disclaimers in the documentation and/or 18 | other materials provided with the distribution. 19 | 20 | In no event shall the authors or copyright holders be liable for any special, 21 | incidental, indirect or consequential damages of any kind, or any damages 22 | whatsoever resulting from loss of use, data or profits, whether or not 23 | advised of the possibility of damage, and on any theory of liability, 24 | arising out of or in connection with the use or performance of this software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 27 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 31 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | DEALINGS WITH THE SOFTWARE 33 | 34 | *****************************************************************************/ 35 | //#include 36 | //#include 37 | #include 38 | #include "aes.h" 39 | #include "cmac.h" 40 | #include "utilities.h" 41 | 42 | #define LSHIFT(v, r) do { \ 43 | int32_t i; \ 44 | for (i = 0; i < 15; i++) \ 45 | (r)[i] = (v)[i] << 1 | (v)[i + 1] >> 7; \ 46 | (r)[15] = (v)[15] << 1; \ 47 | } while (0) 48 | 49 | #define XOR(v, r) do { \ 50 | int32_t i; \ 51 | for (i = 0; i < 16; i++) \ 52 | { \ 53 | (r)[i] = (r)[i] ^ (v)[i]; \ 54 | } \ 55 | } while (0) \ 56 | 57 | 58 | void AES_CMAC_Init(AES_CMAC_CTX *ctx) 59 | { 60 | memset1(ctx->X, 0, sizeof ctx->X); 61 | ctx->M_n = 0; 62 | memset1(ctx->rijndael.ksch, '\0', 240); 63 | } 64 | 65 | void AES_CMAC_SetKey(AES_CMAC_CTX *ctx, const uint8_t key[AES_CMAC_KEY_LENGTH]) 66 | { 67 | //rijndael_set_key_enc_only(&ctx->rijndael, key, 128); 68 | lorawan_aes_set_key( key, AES_CMAC_KEY_LENGTH, &ctx->rijndael); 69 | } 70 | 71 | void AES_CMAC_Update(AES_CMAC_CTX *ctx, const uint8_t *data, uint32_t len) 72 | { 73 | uint32_t mlen; 74 | uint8_t in[16]; 75 | 76 | if (ctx->M_n > 0) { 77 | mlen = MIN(16 - ctx->M_n, len); 78 | memcpy1(ctx->M_last + ctx->M_n, data, mlen); 79 | ctx->M_n += mlen; 80 | if (ctx->M_n < 16 || len == mlen) 81 | return; 82 | XOR(ctx->M_last, ctx->X); 83 | //rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X); 84 | lora_aes_encrypt( ctx->X, ctx->X, &ctx->rijndael); 85 | data += mlen; 86 | len -= mlen; 87 | } 88 | while (len > 16) { /* not last block */ 89 | 90 | XOR(data, ctx->X); 91 | //rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X); 92 | 93 | memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten 94 | lora_aes_encrypt( in, in, &ctx->rijndael); 95 | memcpy1(&ctx->X[0], in, 16); 96 | 97 | data += 16; 98 | len -= 16; 99 | } 100 | /* potential last block, save it */ 101 | memcpy1(ctx->M_last, data, len); 102 | ctx->M_n = len; 103 | } 104 | 105 | void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *ctx) 106 | { 107 | uint8_t K[16]; 108 | uint8_t in[16]; 109 | /* generate subkey K1 */ 110 | memset1(K, '\0', 16); 111 | 112 | //rijndael_encrypt(&ctx->rijndael, K, K); 113 | 114 | lora_aes_encrypt( K, K, &ctx->rijndael); 115 | 116 | if (K[0] & 0x80) { 117 | LSHIFT(K, K); 118 | K[15] ^= 0x87; 119 | } else 120 | LSHIFT(K, K); 121 | 122 | 123 | if (ctx->M_n == 16) { 124 | /* last block was a complete block */ 125 | XOR(K, ctx->M_last); 126 | 127 | } else { 128 | /* generate subkey K2 */ 129 | if (K[0] & 0x80) { 130 | LSHIFT(K, K); 131 | K[15] ^= 0x87; 132 | } else 133 | LSHIFT(K, K); 134 | 135 | /* padding(M_last) */ 136 | ctx->M_last[ctx->M_n] = 0x80; 137 | while (++ctx->M_n < 16) 138 | ctx->M_last[ctx->M_n] = 0; 139 | 140 | XOR(K, ctx->M_last); 141 | 142 | 143 | } 144 | XOR(ctx->M_last, ctx->X); 145 | 146 | //rijndael_encrypt(&ctx->rijndael, ctx->X, digest); 147 | 148 | memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten 149 | lora_aes_encrypt(in, digest, &ctx->rijndael); 150 | memset1(K, 0, sizeof K); 151 | 152 | } 153 | 154 | -------------------------------------------------------------------------------- /src/cmac.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | Copyright (C) 2009 Lander Casado, Philippas Tsigas 3 | 4 | All rights reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files 8 | (the "Software"), to deal with the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | Redistributions of source code must retain the above copyright notice, 15 | this list of conditions and the following disclaimers. Redistributions in 16 | binary form must reproduce the above copyright notice, this list of 17 | conditions and the following disclaimers in the documentation and/or 18 | other materials provided with the distribution. 19 | 20 | In no event shall the authors or copyright holders be liable for any special, 21 | incidental, indirect or consequential damages of any kind, or any damages 22 | whatsoever resulting from loss of use, data or profits, whether or not 23 | advised of the possibility of damage, and on any theory of liability, 24 | arising out of or in connection with the use or performance of this software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 27 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 31 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 32 | DEALINGS WITH THE SOFTWARE 33 | 34 | *****************************************************************************/ 35 | 36 | #ifndef _CMAC_H_ 37 | #define _CMAC_H_ 38 | 39 | #include "aes.h" 40 | 41 | #define AES_CMAC_KEY_LENGTH 16 42 | #define AES_CMAC_DIGEST_LENGTH 16 43 | 44 | typedef struct _AES_CMAC_CTX { 45 | aes_context rijndael; 46 | uint8_t X[16]; 47 | uint8_t M_last[16]; 48 | uint32_t M_n; 49 | } AES_CMAC_CTX; 50 | 51 | //#include 52 | 53 | //__BEGIN_DECLS 54 | void AES_CMAC_Init(AES_CMAC_CTX * ctx); 55 | void AES_CMAC_SetKey(AES_CMAC_CTX * ctx, const uint8_t key[AES_CMAC_KEY_LENGTH]); 56 | void AES_CMAC_Update(AES_CMAC_CTX * ctx, const uint8_t * data, uint32_t len); 57 | // __attribute__((__bounded__(__string__,2,3))); 58 | void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX * ctx); 59 | // __attribute__((__bounded__(__minbytes__,1,AES_CMAC_DIGEST_LENGTH))); 60 | //__END_DECLS 61 | 62 | #endif /* _CMAC_H_ */ 63 | 64 | -------------------------------------------------------------------------------- /src/debug.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file debug.h 3 | * @author MCD Application Team 4 | * @version V1.1.1 5 | * @date 01-June-2017 6 | * @brief Header for driver debug.c module 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2017 STMicroelectronics International N.V. 11 | * All rights reserved.

12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted, provided that the following conditions are met: 15 | * 16 | * 1. Redistribution of source code must retain the above copyright notice, 17 | * this list of conditions and the following disclaimer. 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, 19 | * this list of conditions and the following disclaimer in the documentation 20 | * and/or other materials provided with the distribution. 21 | * 3. Neither the name of STMicroelectronics nor the names of other 22 | * contributors to this software may be used to endorse or promote products 23 | * derived from this software without specific written permission. 24 | * 4. This software, including modifications and/or derivative works of this 25 | * software, must execute solely and exclusively on microcontroller or 26 | * microprocessor devices manufactured by or for STMicroelectronics. 27 | * 5. Redistribution and use of this software other than as permitted under 28 | * this license is void and will automatically terminate your rights under 29 | * this license. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 32 | * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 34 | * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY 35 | * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 36 | * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 37 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 38 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 39 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 40 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 41 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 42 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 | * 44 | ****************************************************************************** 45 | */ 46 | 47 | /* Define to prevent recursive inclusion -------------------------------------*/ 48 | #ifndef __DEBUG_H__ 49 | #define __DEBUG_H__ 50 | 51 | /* Includes ------------------------------------------------------------------*/ 52 | #include 53 | //#include 54 | #include "utilities.h" 55 | 56 | /* Exported types ------------------------------------------------------------*/ 57 | /* Exported constants --------------------------------------------------------*/ 58 | /* External variables --------------------------------------------------------*/ 59 | /* Exported macros -----------------------------------------------------------*/ 60 | typedef enum LOG_LEVEL_E { 61 | LL_NONE, 62 | LL_ERR, 63 | LL_WARN, 64 | LL_DEBUG, 65 | LL_VDEBUG, 66 | LL_ALL 67 | } LOG_LEVEL; 68 | 69 | 70 | #ifdef __cplusplus 71 | extern "C" { 72 | #endif 73 | 74 | extern void lora_printf(const char *format, ...); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | 81 | #define ERR_PRINTF(format, ...) do {}while(0) 82 | #define WARN_PRINTF(format, ...) do {}while(0) 83 | #define VDBG_PRINTF(format, ...) do {}while(0) 84 | #define PRINTF_RAW(...) 85 | #define PRINTF_AT(...) 86 | #define DBG_PRINTF_CRITICAL(p) 87 | 88 | #if LoRaWAN_DEBUG_LEVEL >= 2 89 | #define DBG_PRINTF(format, ...) lora_printf(format, ##__VA_ARGS__) 90 | #define DIO_PRINTF(format, ...) lora_printf(format, ##__VA_ARGS__) 91 | #elif LoRaWAN_DEBUG_LEVEL == 1 92 | #define DBG_PRINTF(format, ...) lora_printf(format, ##__VA_ARGS__) 93 | #define DIO_PRINTF(format, ...) 94 | #else 95 | #define DBG_PRINTF(format, ...) do {}while(0) 96 | #define DIO_PRINTF(format, ...) do {}while(0) 97 | #endif 98 | 99 | #endif /* __DEBUG_H__*/ 100 | 101 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 102 | -------------------------------------------------------------------------------- /src/delay.c: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Delay functions implementation 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #include "board.h" 16 | #include "Arduino.h" 17 | 18 | void DelayMs( uint32_t ms ) 19 | { 20 | delay(ms); 21 | } 22 | -------------------------------------------------------------------------------- /src/delay.h: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Delay functions implementation 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #ifndef __DELAY_H__ 16 | #define __DELAY_H__ 17 | 18 | #ifdef __cplusplus 19 | extern "C"{ 20 | #endif 21 | /*! 22 | * Blocking delay of "s" seconds 23 | */ 24 | void Delay( float s ); 25 | 26 | /*! 27 | * Blocking delay of "ms" milliseconds 28 | */ 29 | void DelayMs( uint32_t ms ); 30 | 31 | #ifdef __cplusplus 32 | } // extern "C" 33 | #endif 34 | 35 | #endif // __DELAY_H__ 36 | 37 | -------------------------------------------------------------------------------- /src/fifo.c: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Implements a FIFO buffer 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #include "fifo.h" 16 | 17 | static uint16_t FifoNext( Fifo_t *fifo, uint16_t index ) 18 | { 19 | return ( index + 1 ) % fifo->Size; 20 | } 21 | 22 | void FifoInit( Fifo_t *fifo, uint8_t *buffer, uint16_t size ) 23 | { 24 | fifo->Begin = 0; 25 | fifo->End = 0; 26 | fifo->Data = buffer; 27 | fifo->Size = size; 28 | } 29 | 30 | void FifoPush( Fifo_t *fifo, uint8_t data ) 31 | { 32 | fifo->End = FifoNext( fifo, fifo->End ); 33 | fifo->Data[fifo->End] = data; 34 | } 35 | 36 | uint8_t FifoPop( Fifo_t *fifo ) 37 | { 38 | uint8_t data = fifo->Data[FifoNext( fifo, fifo->Begin )]; 39 | 40 | fifo->Begin = FifoNext( fifo, fifo->Begin ); 41 | return data; 42 | } 43 | 44 | void FifoFlush( Fifo_t *fifo ) 45 | { 46 | fifo->Begin = 0; 47 | fifo->End = 0; 48 | } 49 | 50 | bool IsFifoEmpty( Fifo_t *fifo ) 51 | { 52 | return ( fifo->Begin == fifo->End ); 53 | } 54 | 55 | bool IsFifoFull( Fifo_t *fifo ) 56 | { 57 | return ( FifoNext( fifo, fifo->End ) == fifo->Begin ); 58 | } 59 | -------------------------------------------------------------------------------- /src/fifo.h: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Implements a FIFO buffer 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #ifndef __FIFO_H__ 16 | #define __FIFO_H__ 17 | 18 | #include 19 | #include 20 | 21 | /*! 22 | * FIFO structure 23 | */ 24 | typedef struct Fifo_s 25 | { 26 | uint16_t Begin; 27 | uint16_t End; 28 | uint8_t *Data; 29 | uint16_t Size; 30 | }Fifo_t; 31 | 32 | /*! 33 | * Initializes the FIFO structure 34 | * 35 | * \param [IN] fifo Pointer to the FIFO object 36 | * \param [IN] buffer Buffer to be used as FIFO 37 | * \param [IN] size Size of the buffer 38 | */ 39 | void FifoInit( Fifo_t *fifo, uint8_t *buffer, uint16_t size ); 40 | 41 | /*! 42 | * Pushes data to the FIFO 43 | * 44 | * \param [IN] fifo Pointer to the FIFO object 45 | * \param [IN] data Data to be pushed into the FIFO 46 | */ 47 | void FifoPush( Fifo_t *fifo, uint8_t data ); 48 | 49 | /*! 50 | * Pops data from the FIFO 51 | * 52 | * \param [IN] fifo Pointer to the FIFO object 53 | * \retval data Data popped from the FIFO 54 | */ 55 | uint8_t FifoPop( Fifo_t *fifo ); 56 | 57 | /*! 58 | * Flushes the FIFO 59 | * 60 | * \param [IN] fifo Pointer to the FIFO object 61 | */ 62 | void FifoFlush( Fifo_t *fifo ); 63 | 64 | /*! 65 | * Checks if the FIFO is empty 66 | * 67 | * \param [IN] fifo Pointer to the FIFO object 68 | * \retval isEmpty true: FIFO is empty, false FIFO is not empty 69 | */ 70 | bool IsFifoEmpty( Fifo_t *fifo ); 71 | 72 | /*! 73 | * Checks if the FIFO is full 74 | * 75 | * \param [IN] fifo Pointer to the FIFO object 76 | * \retval isFull true: FIFO is full, false FIFO is not full 77 | */ 78 | bool IsFifoFull( Fifo_t *fifo ); 79 | 80 | #endif // __FIFO_H__ 81 | -------------------------------------------------------------------------------- /src/gpio-board.c: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file gpio-board.c 3 | * 4 | * \brief Target board GPIO driver implementation 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013-2017 Semtech 16 | * 17 | * \endcode 18 | * 19 | * \author Miguel Luis ( Semtech ) 20 | * 21 | * \author Gregory Cristian ( Semtech ) 22 | */ 23 | #include "utilities.h" 24 | #include "rtc-board.h" 25 | #include "gpio-board.h" 26 | #if defined( BOARD_IOE_EXT ) 27 | #include "gpio-ioe.h" 28 | #endif 29 | 30 | 31 | static GpioIrqHandler *GpioIrq[16]; 32 | 33 | void GpioMcuInit( Gpio_t *obj, uint8_t pin, uint8_t mode, PinConfigs config, PinTypes type, uint32_t value ) 34 | { 35 | obj->pin = pin; 36 | pinMode(pin,mode); 37 | if( mode == OUTPUT ) 38 | { 39 | GpioMcuWrite( obj, value ); 40 | } 41 | } 42 | 43 | void GpioMcuSetInterrupt( Gpio_t *obj, int irqMode, IrqPriorities irqPriority, GpioIrqHandler *irqHandler ) 44 | { 45 | attachInterrupt(obj->pin,irqHandler,irqMode); 46 | } 47 | 48 | void GpioMcuRemoveInterrupt( Gpio_t *obj ) 49 | { 50 | detachInterrupt(obj->pin); 51 | } 52 | 53 | void GpioMcuWrite( Gpio_t *obj, uint32_t value ) 54 | { 55 | digitalWrite(obj->pin,value); 56 | } 57 | 58 | void GpioMcuToggle( Gpio_t *obj ) 59 | { 60 | 61 | } 62 | 63 | uint32_t GpioMcuRead( Gpio_t *obj ) 64 | { 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /src/gpio-board.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file gpio-board.h 3 | * 4 | * \brief Target board GPIO driver implementation 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013-2017 Semtech 16 | * 17 | * \endcode 18 | * 19 | * \author Miguel Luis ( Semtech ) 20 | * 21 | * \author Gregory Cristian ( Semtech ) 22 | */ 23 | #ifndef __GPIO_BOARD_H__ 24 | #define __GPIO_BOARD_H__ 25 | 26 | #include "gpio.h" 27 | 28 | /*! 29 | * \brief Initializes the given GPIO object 30 | * 31 | * \param [IN] obj Pointer to the GPIO object 32 | * \param [IN] pin Pin name ( please look in pinName-board.h file ) 33 | * \param [IN] mode Pin mode [PIN_INPUT, PIN_OUTPUT, 34 | * PIN_ALTERNATE_FCT, PIN_ANALOGIC] 35 | * \param [IN] config Pin config [PIN_PUSH_PULL, PIN_OPEN_DRAIN] 36 | * \param [IN] type Pin type [PIN_NO_PULL, PIN_PULL_UP, PIN_PULL_DOWN] 37 | * \param [IN] value Default output value at initialization 38 | */ 39 | void GpioMcuInit( Gpio_t *obj, uint8_t pin, uint8_t mode, PinConfigs config, PinTypes type, uint32_t value ); 40 | 41 | /*! 42 | * \brief GPIO IRQ Initialization 43 | * 44 | * \param [IN] obj Pointer to the GPIO object 45 | * \param [IN] irqMode IRQ mode [NO_IRQ, IRQ_RISING_EDGE, 46 | * IRQ_FALLING_EDGE, IRQ_RISING_FALLING_EDGE] 47 | * \param [IN] irqPriority IRQ priority [IRQ_VERY_LOW_PRIORITY, IRQ_LOW_PRIORITY 48 | * IRQ_MEDIUM_PRIORITY, IRQ_HIGH_PRIORITY 49 | * IRQ_VERY_HIGH_PRIORITY] 50 | * \param [IN] irqHandler Callback function pointer 51 | */ 52 | void GpioMcuSetInterrupt( Gpio_t *obj, int irqMode, IrqPriorities irqPriority, GpioIrqHandler *irqHandler ); 53 | 54 | /*! 55 | * \brief Removes the interrupt from the object 56 | * 57 | * \param [IN] obj Pointer to the GPIO object 58 | */ 59 | void GpioMcuRemoveInterrupt( Gpio_t *obj ); 60 | 61 | /*! 62 | * \brief Writes the given value to the GPIO output 63 | * 64 | * \param [IN] obj Pointer to the GPIO object 65 | * \param [IN] value New GPIO output value 66 | */ 67 | void GpioMcuWrite( Gpio_t *obj, uint32_t value ); 68 | 69 | /*! 70 | * \brief Toggle the value to the GPIO output 71 | * 72 | * \param [IN] obj Pointer to the GPIO object 73 | */ 74 | void GpioMcuToggle( Gpio_t *obj ); 75 | 76 | /*! 77 | * \brief Reads the current GPIO input value 78 | * 79 | * \param [IN] obj Pointer to the GPIO object 80 | * \retval value Current GPIO input value 81 | */ 82 | uint32_t GpioMcuRead( Gpio_t *obj ); 83 | 84 | #endif // __GPIO_BOARD_H__ 85 | -------------------------------------------------------------------------------- /src/gpio.c: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file gpio.c 3 | * 4 | * \brief GPIO driver implementation 5 | * 6 | * \remark: Relies on the specific board GPIO implementation as well as on 7 | * IO expander driver implementation if one is available on the target 8 | * board. 9 | * 10 | * \copyright Revised BSD License, see section \ref LICENSE. 11 | * 12 | * \code 13 | * ______ _ 14 | * / _____) _ | | 15 | * ( (____ _____ ____ _| |_ _____ ____| |__ 16 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 17 | * _____) ) ____| | | || |_| ____( (___| | | | 18 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 19 | * (C)2013-2017 Semtech 20 | * 21 | * \endcode 22 | * 23 | * \author Miguel Luis ( Semtech ) 24 | * 25 | * \author Gregory Cristian ( Semtech ) 26 | */ 27 | #include "gpio-board.h" 28 | 29 | void GpioInit( Gpio_t *obj, uint8_t pin, uint8_t mode, PinConfigs config, PinTypes type, uint32_t value ) 30 | { 31 | GpioMcuInit( obj, pin, mode, config, type, value ); 32 | } 33 | 34 | void GpioSetInterrupt( Gpio_t *obj, IrqModes irqMode, IrqPriorities irqPriority, GpioIrqHandler *irqHandler ) 35 | { 36 | GpioMcuSetInterrupt( obj, irqMode, irqPriority, irqHandler ); 37 | } 38 | 39 | void GpioRemoveInterrupt( Gpio_t *obj ) 40 | { 41 | GpioMcuRemoveInterrupt( obj ); 42 | } 43 | 44 | void GpioWrite( Gpio_t *obj, uint32_t value ) 45 | { 46 | GpioMcuWrite( obj, value ); 47 | } 48 | 49 | void GpioToggle( Gpio_t *obj ) 50 | { 51 | GpioMcuToggle( obj ); 52 | } 53 | 54 | uint32_t GpioRead( Gpio_t *obj ) 55 | { 56 | return GpioMcuRead( obj ); 57 | } 58 | -------------------------------------------------------------------------------- /src/gpio.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file gpio.h 3 | * 4 | * \brief GPIO driver implementation 5 | * 6 | * \remark: Relies on the specific board GPIO implementation as well as on 7 | * IO expander driver implementation if one is available on the target 8 | * board. 9 | * 10 | * \copyright Revised BSD License, see section \ref LICENSE. 11 | * 12 | * \code 13 | * ______ _ 14 | * / _____) _ | | 15 | * ( (____ _____ ____ _| |_ _____ ____| |__ 16 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 17 | * _____) ) ____| | | || |_| ____( (___| | | | 18 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 19 | * (C)2013-2017 Semtech 20 | * 21 | * \endcode 22 | * 23 | * \author Miguel Luis ( Semtech ) 24 | * 25 | * \author Gregory Cristian ( Semtech ) 26 | */ 27 | #ifndef __GPIO_H__ 28 | #define __GPIO_H__ 29 | 30 | #include 31 | #include "pinName-board.h" 32 | #include "pinName-ioe.h" 33 | 34 | 35 | /*! 36 | * Add a pull-up, a pull-down or nothing on the GPIO line 37 | */ 38 | typedef enum 39 | { 40 | PIN_NO_PULL = 0, 41 | PIN_PULL_UP, 42 | PIN_PULL_DOWN 43 | }PinTypes; 44 | 45 | /*! 46 | * Define the GPIO as Push-pull type or Open Drain 47 | */ 48 | typedef enum 49 | { 50 | PIN_PUSH_PULL = 0, 51 | PIN_OPEN_DRAIN 52 | }PinConfigs; 53 | 54 | /*! 55 | * Define the GPIO IRQ on a rising, falling or both edges 56 | */ 57 | typedef enum 58 | { 59 | NO_IRQ = 0, 60 | IRQ_RISING_EDGE, 61 | IRQ_FALLING_EDGE, 62 | IRQ_RISING_FALLING_EDGE 63 | }IrqModes; 64 | 65 | /*! 66 | * Define the IRQ priority on the GPIO 67 | */ 68 | typedef enum 69 | { 70 | IRQ_VERY_LOW_PRIORITY = 0, 71 | IRQ_LOW_PRIORITY, 72 | IRQ_MEDIUM_PRIORITY, 73 | IRQ_HIGH_PRIORITY, 74 | IRQ_VERY_HIGH_PRIORITY 75 | }IrqPriorities; 76 | 77 | /*! 78 | * Structure for the GPIO 79 | */ 80 | typedef struct 81 | { 82 | uint8_t pin; 83 | uint16_t pinIndex; 84 | void *port; 85 | uint16_t portIndex; 86 | PinTypes pull; 87 | }Gpio_t; 88 | 89 | /*! 90 | * GPIO IRQ handler function prototype 91 | */ 92 | typedef void( GpioIrqHandler )( void ); 93 | 94 | /*! 95 | * GPIO Expander IRQ handler function prototype 96 | */ 97 | typedef void( GpioIoeIrqHandler )( void ); 98 | 99 | /*! 100 | * \brief Initializes the given GPIO object 101 | * 102 | * \param [IN] obj Pointer to the GPIO object 103 | * \param [IN] pin Pin name ( please look in pinName-board.h file ) 104 | * \param [IN] mode Pin mode [PIN_INPUT, PIN_OUTPUT, 105 | * PIN_ALTERNATE_FCT, PIN_ANALOGIC] 106 | * \param [IN] config Pin config [PIN_PUSH_PULL, PIN_OPEN_DRAIN] 107 | * \param [IN] type Pin type [PIN_NO_PULL, PIN_PULL_UP, PIN_PULL_DOWN] 108 | * \param [IN] value Default output value at initialization 109 | */ 110 | void GpioInit( Gpio_t *obj, uint8_t pin, uint8_t mode, PinConfigs config, PinTypes type, uint32_t value ); 111 | 112 | /*! 113 | * \brief GPIO IRQ Initialization 114 | * 115 | * \param [IN] obj Pointer to the GPIO object 116 | * \param [IN] irqMode IRQ mode [NO_IRQ, IRQ_RISING_EDGE, 117 | * IRQ_FALLING_EDGE, IRQ_RISING_FALLING_EDGE] 118 | * \param [IN] irqPriority IRQ priority [IRQ_VERY_LOW_PRIORITY, IRQ_LOW_PRIORITY 119 | * IRQ_MEDIUM_PRIORITY, IRQ_HIGH_PRIORITY 120 | * IRQ_VERY_HIGH_PRIORITY] 121 | * \param [IN] irqHandler Callback function pointer 122 | */ 123 | void GpioSetInterrupt( Gpio_t *obj, IrqModes irqMode, IrqPriorities irqPriority, GpioIrqHandler *irqHandler ); 124 | 125 | /*! 126 | * \brief Removes the interrupt from the object 127 | * 128 | * \param [IN] obj Pointer to the GPIO object 129 | */ 130 | void GpioRemoveInterrupt( Gpio_t *obj ); 131 | 132 | /*! 133 | * \brief Writes the given value to the GPIO output 134 | * 135 | * \param [IN] obj Pointer to the GPIO object 136 | * \param [IN] value New GPIO output value 137 | */ 138 | void GpioWrite( Gpio_t *obj, uint32_t value ); 139 | 140 | /*! 141 | * \brief Toggle the value to the GPIO output 142 | * 143 | * \param [IN] obj Pointer to the GPIO object 144 | */ 145 | void GpioToggle( Gpio_t *obj ); 146 | 147 | /*! 148 | * \brief Reads the current GPIO input value 149 | * 150 | * \param [IN] obj Pointer to the GPIO object 151 | * \retval value Current GPIO input value 152 | */ 153 | uint32_t GpioRead( Gpio_t *obj ); 154 | 155 | #endif // __GPIO_H__ 156 | -------------------------------------------------------------------------------- /src/lorawan_spi.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file spi-board.h 3 | * 4 | * \brief SPI driver implementation 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013-2017 Semtech 16 | * 17 | * \endcode 18 | * 19 | * \author Miguel Luis ( Semtech ) 20 | * 21 | * \author Gregory Cristian ( Semtech ) 22 | */ 23 | #ifndef __Lorawan_SPI_H__ 24 | #define __Lorawan_SPI_H__ 25 | 26 | #include "gpio.h" 27 | 28 | /*! 29 | * SPI peripheral ID 30 | */ 31 | typedef enum 32 | { 33 | SPI_1, 34 | SPI_2, 35 | }SpiId_t; 36 | 37 | /*! 38 | * SPI object type definition 39 | */ 40 | typedef struct Spi_s 41 | { 42 | SpiId_t SpiId; 43 | Gpio_t Mosi; 44 | Gpio_t Miso; 45 | Gpio_t Sclk; 46 | Gpio_t Nss; 47 | }Spi_t; 48 | 49 | /*! 50 | * \brief Initializes the SPI object and MCU peripheral 51 | * 52 | * \remark When NSS pin is software controlled set the pin name to NC otherwise 53 | * set the pin name to be used. 54 | * 55 | * \param [IN] obj SPI object 56 | * \param [IN] mosi SPI MOSI pin name to be used 57 | * \param [IN] miso SPI MISO pin name to be used 58 | * \param [IN] sclk SPI SCLK pin name to be used 59 | * \param [IN] nss SPI NSS pin name to be used 60 | */ 61 | void SpiInit( Spi_t *obj, SpiId_t spiId, uint8_t mosi, uint8_t miso, uint8_t sclk, uint8_t nss ); 62 | 63 | /*! 64 | * \brief De-initializes the SPI object and MCU peripheral 65 | * 66 | * \param [IN] obj SPI object 67 | */ 68 | void SpiDeInit( Spi_t *obj ); 69 | 70 | /*! 71 | * \brief Configures the SPI peripheral 72 | * 73 | * \remark Slave mode isn't currently handled 74 | * 75 | * \param [IN] obj SPI object 76 | * \param [IN] bits Number of bits to be used. [8 or 16] 77 | * \param [IN] cpol Clock polarity 78 | * \param [IN] cpha Clock phase 79 | * \param [IN] slave When set the peripheral acts in slave mode 80 | */ 81 | void SpiFormat( Spi_t *obj, int8_t bits, int8_t cpol, int8_t cpha, int8_t slave ); 82 | 83 | /*! 84 | * \brief Sets the SPI speed 85 | * 86 | * \param [IN] obj SPI object 87 | * \param [IN] hz SPI clock frequency in hz 88 | */ 89 | void SpiFrequency( Spi_t *obj, uint32_t hz ); 90 | 91 | /*! 92 | * \brief Sends outData and receives inData 93 | * 94 | * \param [IN] obj SPI object 95 | * \param [IN] outData Byte to be sent 96 | * \retval inData Received byte. 97 | */ 98 | uint16_t SpiInOut( Spi_t *obj, uint16_t outData ); 99 | 100 | #endif // __SPI_H__ 101 | -------------------------------------------------------------------------------- /src/pinName-board.h: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Bleeper STM32L151RD microcontroller pins definition 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #ifndef __PIN_NAME_MCU_H__ 16 | #define __PIN_NAME_MCU_H__ 17 | 18 | /*! 19 | * STM32 Pin Names 20 | */ 21 | #define MCU_PINS \ 22 | PA_0 = 0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, PA_8, PA_9, PA_10, PA_11, PA_12, PA_13, PA_14, PA_15, \ 23 | PB_0, PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8, PB_9, PB_10, PB_11, PB_12, PB_13, PB_14, PB_15, \ 24 | PC_0, PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9, PC_10, PC_11, PC_12, PC_13, PC_14, PC_15, \ 25 | PD_0, PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, PD_10, PD_11, PD_12, PD_13, PD_14, PD_15, \ 26 | PE_0, PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_10, PE_11, PE_12, PE_13, PE_14, PE_15, \ 27 | PF_0, PF_1, PF_2, PF_3, PF_4, PF_5, PF_6, PF_7, PF_8, PF_9, PF_10, PF_11, PF_12, PF_13, PF_14, PF_15, \ 28 | PH_0, PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7, PH_8, PH_9, PH_10, PH_11, PH_12, PH_13, PH_14, PH_15 29 | 30 | #endif // __PIN_NAME_MCU_H__ 31 | -------------------------------------------------------------------------------- /src/pinName-ioe.h: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Bleeper STM32L151RD microcontroller pins definition 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #ifndef __PIN_NAME_IOE_H__ 16 | #define __PIN_NAME_IOE_H__ 17 | 18 | // SX1509 Pin Names 19 | #define IOE_PINS \ 20 | IOE_0, IOE_1, IOE_2, IOE_3, IOE_4, IOE_5, IOE_6, IOE_7, \ 21 | IOE_8, IOE_9, IOE_10, IOE_11, IOE_12, IOE_13, IOE_14, IOE_15 22 | #endif // __PIN_NAME_IOE_H__ 23 | -------------------------------------------------------------------------------- /src/rtc-board.h: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: MCU RTC timer and low power modes management 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #ifndef __RTC_BOARD_H__ 16 | #define __RTC_BOARD_H__ 17 | #include "soc/rtc.h" 18 | #include "timer.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C"{ 22 | #endif 23 | 24 | extern hw_timer_t * timer; 25 | extern uint32_t TimeSwitch; 26 | extern uint64_t preAlarmtimer; 27 | extern uint64_t nextAlarm; 28 | extern TimerEvent_t *TimerListHead; 29 | /*! 30 | * \brief Timer time variable definition 31 | */ 32 | /*! 33 | * \brief Start the RTC timer 34 | * 35 | * \remark The timer is based on the RTC Alarm running at 32.768KHz 36 | * 37 | * \param[IN] timeout Duration of the Timer 38 | */ 39 | void TimerSetTime( uint64_t timeout ); 40 | 41 | /*! 42 | * \brief Adjust the value of the timeout to handle wakeup time from Alarm and GPIO irq 43 | * 44 | * \param[IN] timeout Duration of the Timer without compensation for wakeup time 45 | * \retval new value for the Timeout with compensations 46 | */ 47 | TimerTime_t TimerGetAdjustedTimeoutValue( uint32_t timeout ); 48 | 49 | /*! 50 | * \brief Get the RTC timer value 51 | * 52 | * \retval RTC Timer value 53 | */ 54 | TimerTime_t TimerGetTimerValue( void ); 55 | 56 | /*! 57 | * \brief Get the RTC timer elapsed time since the last Alarm was set 58 | * 59 | * \retval RTC Elapsed time since the last alarm 60 | */ 61 | TimerTime_t TimerGetElapsedAlarmTime( void ); 62 | 63 | /*! 64 | * \brief Compute the timeout time of a future event in time 65 | * 66 | * \param[IN] futureEventInTime Value in time 67 | * \retval time Time between now and the futureEventInTime 68 | */ 69 | TimerTime_t TimerComputeFutureEventTime( TimerTime_t futureEventInTime ); 70 | 71 | /*! 72 | * \brief Compute the elapsed time since a fix event in time 73 | * 74 | * \param[IN] eventInTime Value in time 75 | * \retval elapsed Time since the eventInTime 76 | */ 77 | TimerTime_t TimerComputeElapsedTime( TimerTime_t eventInTime ); 78 | 79 | /*! 80 | * \brief This function blocks the MCU from going into Low Power mode 81 | * 82 | * \param [IN] status [true: Enable, false: Disable 83 | */ 84 | void BlockLowPowerDuringTask ( bool status ); 85 | 86 | /*! 87 | * \brief Sets the MCU into low power STOP mode 88 | */ 89 | void RtcEnterLowPowerStopMode( void ); 90 | 91 | /*! 92 | * \brief Restore the MCU to its normal operation mode 93 | */ 94 | void RtcRecoverMcuStatus( void ); 95 | 96 | 97 | #ifdef __cplusplus 98 | } // extern "C" 99 | #endif 100 | 101 | #endif // __RTC_BOARD_H__ 102 | -------------------------------------------------------------------------------- /src/sensor/HDC1080.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Arduino Library for Texas Instruments HDC1080 Digital Humidity and Temperature Sensor 4 | Written by AA for ClosedCube 5 | --- 6 | 7 | The MIT License (MIT) 8 | 9 | Copyright (c) 2016-2017 ClosedCube Limited 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in 19 | all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | THE SOFTWARE. 28 | 29 | */ 30 | 31 | #include 32 | 33 | #include "HDC1080.h" 34 | 35 | 36 | HDC1080::HDC1080() 37 | { 38 | } 39 | 40 | void HDC1080::begin(uint8_t address) { 41 | _address = address; 42 | Wire.begin(); 43 | 44 | setResolution(HDC1080_RESOLUTION_14BIT, HDC1080_RESOLUTION_14BIT); 45 | } 46 | 47 | void HDC1080::end() { 48 | Wire.endTransmission(); 49 | } 50 | 51 | 52 | void HDC1080::setResolution(HDC1080_MeasurementResolution humidity, HDC1080_MeasurementResolution temperature) { 53 | HDC1080_Registers reg; 54 | reg.HumidityMeasurementResolution = 0; 55 | reg.TemperatureMeasurementResolution = 0; 56 | 57 | if (temperature == HDC1080_RESOLUTION_11BIT) 58 | reg.TemperatureMeasurementResolution = 0x01; 59 | 60 | switch (humidity) 61 | { 62 | case HDC1080_RESOLUTION_8BIT: 63 | reg.HumidityMeasurementResolution = 0x02; 64 | break; 65 | case HDC1080_RESOLUTION_11BIT: 66 | reg.HumidityMeasurementResolution = 0x01; 67 | break; 68 | default: 69 | break; 70 | } 71 | 72 | writeRegister(reg); 73 | } 74 | 75 | HDC1080_SerialNumber HDC1080::readSerialNumber() { 76 | HDC1080_SerialNumber sernum; 77 | sernum.serialFirst = readData(HDC1080_SERIAL_ID_FIRST); 78 | sernum.serialMid = readData(HDC1080_SERIAL_ID_MID); 79 | sernum.serialLast = readData(HDC1080_SERIAL_ID_LAST); 80 | return sernum; 81 | } 82 | 83 | HDC1080_Registers HDC1080::readRegister() { 84 | HDC1080_Registers reg; 85 | reg.rawData = (readData(HDC1080_CONFIGURATION) >> 8); 86 | return reg; 87 | } 88 | 89 | void HDC1080::writeRegister(HDC1080_Registers reg) { 90 | Wire.beginTransmission(_address); 91 | Wire.write(HDC1080_CONFIGURATION); 92 | Wire.write(reg.rawData); 93 | Wire.write(0x00); 94 | Wire.endTransmission(); 95 | delay(10); 96 | } 97 | 98 | void HDC1080::heatUp(uint8_t seconds) { 99 | HDC1080_Registers reg = readRegister(); 100 | reg.Heater = 1; 101 | reg.ModeOfAcquisition = 1; 102 | writeRegister(reg); 103 | 104 | uint8_t buf[4]; 105 | for (int i = 1; i < (seconds*66); i++) { 106 | Wire.beginTransmission(_address); 107 | Wire.write(0x00); 108 | Wire.endTransmission(); 109 | delay(20); 110 | Wire.requestFrom(_address, (uint8_t)4); 111 | Wire.readBytes(buf, (size_t)4); 112 | } 113 | reg.Heater = 0; 114 | reg.ModeOfAcquisition = 0; 115 | writeRegister(reg); 116 | } 117 | 118 | 119 | double HDC1080::readT() { 120 | return readTemperature(); 121 | } 122 | 123 | double HDC1080::readTemperature() { 124 | uint16_t rawT = readData(HDC1080_TEMPERATURE); 125 | return (rawT / pow(2, 16)) * 165.0 - 40.0; 126 | } 127 | 128 | double HDC1080::readH() { 129 | return readHumidity(); 130 | } 131 | 132 | double HDC1080::readHumidity() { 133 | uint16_t rawH = readData(HDC1080_HUMIDITY); 134 | return (rawH / pow(2, 16)) * 100.0; 135 | } 136 | 137 | uint16_t HDC1080::readManufacturerId() { 138 | return readData(HDC1080_MANUFACTURER_ID); 139 | } 140 | 141 | uint16_t HDC1080::readDeviceId() { 142 | return readData(HDC1080_DEVICE_ID); 143 | } 144 | 145 | uint16_t HDC1080::readData(uint8_t pointer) { 146 | Wire.beginTransmission(_address); 147 | Wire.write(pointer); 148 | Wire.endTransmission(); 149 | 150 | delay(9); 151 | Wire.requestFrom(_address, (uint8_t)2); 152 | 153 | byte msb = Wire.read(); 154 | byte lsb = Wire.read(); 155 | 156 | return msb << 8 | lsb; 157 | } 158 | -------------------------------------------------------------------------------- /src/sensor/HDC1080.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Arduino Library for Texas Instruments HDC1080 Digital Humidity and Temperature Sensor 4 | Written by AA for ClosedCube 5 | --- 6 | 7 | The MIT License (MIT) 8 | 9 | Copyright (c) 2016-2017 ClosedCube Limited 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining a copy 12 | of this software and associated documentation files (the "Software"), to deal 13 | in the Software without restriction, including without limitation the rights 14 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | copies of the Software, and to permit persons to whom the Software is 16 | furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in 19 | all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | THE SOFTWARE. 28 | 29 | */ 30 | 31 | #ifndef _HDC1080_h 32 | 33 | #define _HDC1080_h 34 | #include 35 | 36 | typedef enum { 37 | HDC1080_RESOLUTION_8BIT, 38 | HDC1080_RESOLUTION_11BIT, 39 | HDC1080_RESOLUTION_14BIT, 40 | } HDC1080_MeasurementResolution; 41 | 42 | typedef enum { 43 | HDC1080_TEMPERATURE = 0x00, 44 | HDC1080_HUMIDITY = 0x01, 45 | HDC1080_CONFIGURATION = 0x02, 46 | HDC1080_MANUFACTURER_ID = 0xFE, 47 | HDC1080_DEVICE_ID = 0xFF, 48 | HDC1080_SERIAL_ID_FIRST = 0xFB, 49 | HDC1080_SERIAL_ID_MID = 0xFC, 50 | HDC1080_SERIAL_ID_LAST = 0xFD, 51 | } HDC1080_Pointers; 52 | 53 | typedef union { 54 | uint8_t rawData[6]; 55 | struct { 56 | uint16_t serialFirst; 57 | uint16_t serialMid; 58 | uint16_t serialLast; 59 | }; 60 | } HDC1080_SerialNumber; 61 | 62 | typedef union { 63 | uint8_t rawData; 64 | struct { 65 | uint8_t HumidityMeasurementResolution : 2; 66 | uint8_t TemperatureMeasurementResolution : 1; 67 | uint8_t BatteryStatus : 1; 68 | uint8_t ModeOfAcquisition : 1; 69 | uint8_t Heater : 1; 70 | uint8_t ReservedAgain : 1; 71 | uint8_t SoftwareReset : 1; 72 | }; 73 | } HDC1080_Registers; 74 | 75 | class HDC1080 { 76 | public: 77 | HDC1080(); 78 | 79 | void begin(uint8_t address); 80 | void end(); 81 | uint16_t readManufacturerId(); // 0x5449 ID of Texas Instruments 82 | uint16_t readDeviceId(); // 0x1050 ID of the device 83 | 84 | HDC1080_Registers readRegister(); 85 | void writeRegister(HDC1080_Registers reg); 86 | 87 | HDC1080_SerialNumber readSerialNumber(); 88 | 89 | void heatUp(uint8_t seconds); 90 | 91 | void setResolution(HDC1080_MeasurementResolution humidity, HDC1080_MeasurementResolution temperature); 92 | 93 | double readTemperature(); 94 | double readHumidity(); 95 | 96 | double readT(); // short-cut for readTemperature 97 | double readH(); // short-cut for readHumidity 98 | 99 | private: 100 | uint8_t _address; 101 | uint16_t readData(uint8_t pointer); 102 | 103 | }; 104 | 105 | #endif 106 | 107 | -------------------------------------------------------------------------------- /src/sx1276-board.c: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file sx1276mb1las-board.c 3 | * 4 | * \brief Target board SX1276MB1LAS shield driver implementation 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013-2017 Semtech 16 | * 17 | * \endcode 18 | * 19 | * \author Miguel Luis ( Semtech ) 20 | * 21 | * \author Gregory Cristian ( Semtech ) 22 | */ 23 | #include 24 | #include "utilities.h" 25 | #include "board-config.h" 26 | #include "delay.h" 27 | #include "radio.h" 28 | #include "sx1276-board.h" 29 | #include 30 | /*! 31 | * Flag used to set the RF switch control pins in low power mode when the radio is not active. 32 | */ 33 | static bool RadioIsActive = false; 34 | 35 | /*! 36 | * Radio driver structure initialization 37 | */ 38 | const struct Radio_s Radio = 39 | { 40 | SX1276Init, 41 | SX1276GetStatus, 42 | SX1276SetModem, 43 | SX1276SetChannel, 44 | SX1276IsChannelFree, 45 | SX1276Random, 46 | SX1276SetRxConfig, 47 | SX1276SetTxConfig, 48 | SX1276CheckRfFrequency, 49 | SX1276GetTimeOnAir, 50 | SX1276Send, 51 | SX1276SetSleep, 52 | SX1276SetStby, 53 | SX1276SetRx, 54 | SX1276StartCad, 55 | SX1276SetTxContinuousWave, 56 | SX1276ReadRssi, 57 | SX1276Write, 58 | SX1276Read, 59 | SX1276WriteBuffer, 60 | SX1276ReadBuffer, 61 | SX1276SetMaxPayloadLength, 62 | SX1276SetPublicNetwork, 63 | SX1276GetWakeupTime, 64 | RadioIrqProcess 65 | }; 66 | 67 | /*! 68 | * Antenna switch GPIO pins objects 69 | */ 70 | Gpio_t AntSwitch; 71 | 72 | void SX1276IoInit( void ) 73 | { 74 | GpioInit( &SX1276.Spi.Nss, RADIO_NSS, OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 1 ); 75 | GpioInit( &SX1276.DIO0, RADIO_DIO_0, INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 ); 76 | GpioInit( &SX1276.DIO1, RADIO_DIO_1, INPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 ); 77 | 78 | } 79 | 80 | void SX1276IoIrqInit( DioIrqHandler **irqHandlers ) 81 | { 82 | GpioSetInterrupt( &SX1276.DIO0, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[0] ); 83 | GpioSetInterrupt( &SX1276.DIO1, IRQ_RISING_EDGE, IRQ_HIGH_PRIORITY, irqHandlers[1] ); 84 | 85 | } 86 | 87 | void SX1276IoDeInit( void ) 88 | { 89 | GpioInit( &SX1276.Spi.Nss, RADIO_NSS, OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1 ); 90 | 91 | GpioInit( &SX1276.DIO0, RADIO_DIO_0, INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); 92 | GpioInit( &SX1276.DIO1, RADIO_DIO_1, INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); 93 | } 94 | 95 | /*! 96 | * \brief Enables/disables the TCXO if available on board design. 97 | * 98 | * \param [IN] state TCXO enabled when true and disabled when false. 99 | */ 100 | static void SX1276SetBoardTcxo( uint8_t state ) 101 | { 102 | // No TCXO component available on this board design. 103 | #if 0 104 | if( state == true ) 105 | { 106 | TCXO_ON( ); 107 | DelayMs( BOARD_TCXO_WAKEUP_TIME ); 108 | } 109 | else 110 | { 111 | TCXO_OFF( ); 112 | } 113 | #endif 114 | } 115 | 116 | uint32_t SX1276GetBoardTcxoWakeupTime( void ) 117 | { 118 | return BOARD_TCXO_WAKEUP_TIME; 119 | } 120 | 121 | void SX1276Reset( void ) 122 | { 123 | // Set RESET pin to 0 124 | digitalWrite(RADIO_RESET, LOW); 125 | // Wait 1 ms 126 | DelayMs( 1 ); 127 | 128 | // Configure RESET as input 129 | digitalWrite(RADIO_RESET, HIGH); 130 | 131 | // Wait 6 ms 132 | DelayMs( 6 ); 133 | } 134 | 135 | void SX1276SetRfTxPower( int8_t power ) 136 | { 137 | uint8_t paConfig = 0; 138 | uint8_t paDac = 0; 139 | 140 | paConfig = SX1276Read( REG_PACONFIG ); 141 | paDac = SX1276Read( REG_PADAC ); 142 | 143 | paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | SX1276GetPaSelect( SX1276.Settings.Channel ); 144 | paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70; 145 | 146 | if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST ) 147 | { 148 | paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON; 149 | //if( power > 17 ) 150 | //{ 151 | // paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON; 152 | // } 153 | // else 154 | // { 155 | // paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF; 156 | //} 157 | if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON ) 158 | { 159 | if( power < 5 ) 160 | { 161 | power = 5; 162 | } 163 | if( power > 20 ) 164 | { 165 | power = 20; 166 | } 167 | paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F ); 168 | } 169 | else 170 | { 171 | if( power < 2 ) 172 | { 173 | power = 2; 174 | } 175 | if( power > 17 ) 176 | { 177 | power = 17; 178 | } 179 | paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F ); 180 | } 181 | } 182 | else 183 | { 184 | if( power < -1 ) 185 | { 186 | power = -1; 187 | } 188 | if( power > 14 ) 189 | { 190 | power = 14; 191 | } 192 | paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F ); 193 | } 194 | SX1276Write( REG_PACONFIG, paConfig ); 195 | SX1276Write( REG_PADAC, paDac ); 196 | } 197 | 198 | uint8_t SX1276GetPaSelect( uint32_t channel ) 199 | { 200 | /*if( channel > RF_MID_BAND_THRESH ) 201 | { 202 | return RF_PACONFIG_PASELECT_PABOOST; 203 | } 204 | else 205 | { 206 | return RF_PACONFIG_PASELECT_RFO; 207 | }*/ 208 | return RF_PACONFIG_PASELECT_PABOOST; 209 | } 210 | 211 | void SX1276SetAntSwLowPower( bool status ) 212 | { 213 | if( RadioIsActive != status ) 214 | { 215 | RadioIsActive = status; 216 | 217 | if( status == false ) 218 | { 219 | SX1276SetBoardTcxo( true ); 220 | SX1276AntSwInit( ); 221 | } 222 | else 223 | { 224 | SX1276SetBoardTcxo( false ); 225 | SX1276AntSwDeInit( ); 226 | } 227 | } 228 | } 229 | 230 | void SX1276AntSwInit( void ) 231 | { 232 | // GpioInit( &AntSwitch, RADIO_ANT_SWITCH, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 0 ); 233 | } 234 | 235 | void SX1276AntSwDeInit( void ) 236 | { 237 | // GpioInit( &AntSwitch, RADIO_ANT_SWITCH, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); 238 | } 239 | 240 | void SX1276SetAntSw( uint8_t opMode ) 241 | { 242 | switch( opMode ) 243 | { 244 | case RFLR_OPMODE_TRANSMITTER: 245 | GpioWrite( &AntSwitch, 1 ); 246 | break; 247 | case RFLR_OPMODE_RECEIVER: 248 | case RFLR_OPMODE_RECEIVER_SINGLE: 249 | case RFLR_OPMODE_CAD: 250 | default: 251 | GpioWrite( &AntSwitch, 0 ); 252 | break; 253 | } 254 | } 255 | 256 | bool SX1276CheckRfFrequency( uint32_t frequency ) 257 | { 258 | // Implement check. Currently all frequencies are supported 259 | return true; 260 | } 261 | -------------------------------------------------------------------------------- /src/sx1276-board.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * \file sx1276-board.h 3 | * 4 | * \brief Target board SX1276 driver implementation 5 | * 6 | * \copyright Revised BSD License, see section \ref LICENSE. 7 | * 8 | * \code 9 | * ______ _ 10 | * / _____) _ | | 11 | * ( (____ _____ ____ _| |_ _____ ____| |__ 12 | * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 | * _____) ) ____| | | || |_| ____( (___| | | | 14 | * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 | * (C)2013-2017 Semtech 16 | * 17 | * \endcode 18 | * 19 | * \author Miguel Luis ( Semtech ) 20 | * 21 | * \author Gregory Cristian ( Semtech ) 22 | */ 23 | #ifndef __SX1276_BOARD_H__ 24 | #define __SX1276_BOARD_H__ 25 | 26 | #include 27 | #include 28 | #include "sx1276.h" 29 | 30 | /*! 31 | * \brief Radio hardware registers initialization definition 32 | * 33 | * \remark Can be automatically generated by the SX1276 GUI (not yet implemented) 34 | */ 35 | #define RADIO_INIT_REGISTERS_VALUE \ 36 | { \ 37 | { MODEM_FSK , REG_LNA , 0x23 },\ 38 | { MODEM_FSK , REG_RXCONFIG , 0x1E },\ 39 | { MODEM_FSK , REG_RSSICONFIG , 0xD2 },\ 40 | { MODEM_FSK , REG_AFCFEI , 0x01 },\ 41 | { MODEM_FSK , REG_PREAMBLEDETECT , 0xAA },\ 42 | { MODEM_FSK , REG_OSC , 0x07 },\ 43 | { MODEM_FSK , REG_SYNCCONFIG , 0x12 },\ 44 | { MODEM_FSK , REG_SYNCVALUE1 , 0xC1 },\ 45 | { MODEM_FSK , REG_SYNCVALUE2 , 0x94 },\ 46 | { MODEM_FSK , REG_SYNCVALUE3 , 0xC1 },\ 47 | { MODEM_FSK , REG_PACKETCONFIG1 , 0xD8 },\ 48 | { MODEM_FSK , REG_FIFOTHRESH , 0x8F },\ 49 | { MODEM_FSK , REG_IMAGECAL , 0x02 },\ 50 | { MODEM_FSK , REG_DIOMAPPING1 , 0x00 },\ 51 | { MODEM_FSK , REG_DIOMAPPING2 , 0x30 },\ 52 | { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0xFF },\ 53 | } \ 54 | 55 | #define RF_MID_BAND_THRESH 525000000 56 | 57 | /*! 58 | * \brief Initializes the radio I/Os pins interface 59 | */ 60 | void SX1276IoInit( void ); 61 | 62 | /*! 63 | * \brief Initializes DIO IRQ handlers 64 | * 65 | * \param [IN] irqHandlers Array containing the IRQ callback functions 66 | */ 67 | void SX1276IoIrqInit( DioIrqHandler **irqHandlers ); 68 | 69 | /*! 70 | * \brief De-initializes the radio I/Os pins interface. 71 | * 72 | * \remark Useful when going in MCU low power modes 73 | */ 74 | void SX1276IoDeInit( void ); 75 | 76 | /*! 77 | * \brief Resets the radio 78 | */ 79 | void SX1276Reset( void ); 80 | 81 | /*! 82 | * \brief Sets the radio output power. 83 | * 84 | * \param [IN] power Sets the RF output power 85 | */ 86 | void SX1276SetRfTxPower( int8_t power ); 87 | 88 | /*! 89 | * \brief Gets the board PA selection configuration 90 | * 91 | * \param [IN] channel Channel frequency in Hz 92 | * \retval PaSelect RegPaConfig PaSelect value 93 | */ 94 | uint8_t SX1276GetPaSelect( uint32_t channel ); 95 | 96 | /*! 97 | * \brief Set the RF Switch I/Os pins in low power mode 98 | * 99 | * \param [IN] status enable or disable 100 | */ 101 | void SX1276SetAntSwLowPower( bool status ); 102 | 103 | /*! 104 | * \brief Initializes the RF Switch I/Os pins interface 105 | */ 106 | void SX1276AntSwInit( void ); 107 | 108 | /*! 109 | * \brief De-initializes the RF Switch I/Os pins interface 110 | * 111 | * \remark Needed to decrease the power consumption in MCU low power modes 112 | */ 113 | void SX1276AntSwDeInit( void ); 114 | 115 | /*! 116 | * \brief Controls the antenna switch if necessary. 117 | * 118 | * \remark see errata note 119 | * 120 | * \param [IN] opMode Current radio operating mode 121 | */ 122 | void SX1276SetAntSw( uint8_t opMode ); 123 | 124 | /*! 125 | * \brief Checks if the given RF frequency is supported by the hardware 126 | * 127 | * \param [IN] frequency RF frequency to be checked 128 | * \retval isSupported [true: supported, false: unsupported] 129 | */ 130 | bool SX1276CheckRfFrequency( uint32_t frequency ); 131 | 132 | /*! 133 | * \brief Gets the Defines the time required for the TCXO to wakeup [ms]. 134 | * 135 | * \retval time Board TCXO wakeup time in ms. 136 | */ 137 | uint32_t SX1276GetBoardTcxoWakeupTime( void ); 138 | 139 | /*! 140 | * Radio hardware and global parameters 141 | */ 142 | extern SX1276_t SX1276; 143 | 144 | #endif // __SX1276_BOARD_H__ 145 | -------------------------------------------------------------------------------- /src/timer.h: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Timer objects and scheduling management 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #ifndef __TIMER_H__ 16 | #define __TIMER_H__ 17 | 18 | #include "Arduino.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C"{ 22 | #endif 23 | 24 | /*! 25 | * \brief Timer object description 26 | */ 27 | typedef struct TimerEvent_s 28 | { 29 | uint32_t Timestamp; //! Current timer value 30 | uint32_t ReloadValue; //! Timer delay value 31 | bool IsRunning; //! Is the timer currently running 32 | void ( *Callback )( void ); //! Timer IRQ callback function 33 | struct TimerEvent_s *Next; //! Pointer to the next Timer object. 34 | }TimerEvent_t; 35 | 36 | /*! 37 | * \brief Timer time variable definition 38 | */ 39 | #ifndef TimerTime_t 40 | typedef uint64_t TimerTime_t; 41 | #endif 42 | 43 | /*! 44 | * \brief Initializes the timer object 45 | * 46 | * \remark TimerSetValue function must be called before starting the timer. 47 | * this function initializes timestamp and reload value at 0. 48 | * 49 | * \param [IN] obj Structure containing the timer object parameters 50 | * \param [IN] callback Function callback called at the end of the timeout 51 | */ 52 | void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) ); 53 | 54 | 55 | /*! 56 | * \brief Starts and adds the timer object to the list of timer events 57 | * 58 | * \param [IN] obj Structure containing the timer object parameters 59 | */ 60 | void TimerStart( TimerEvent_t *obj ); 61 | 62 | /*! 63 | * \brief Stops and removes the timer object from the list of timer events 64 | * 65 | * \param [IN] obj Structure containing the timer object parameters 66 | */ 67 | void TimerStop( TimerEvent_t *obj ); 68 | 69 | /*! 70 | * \brief Resets the timer object 71 | * 72 | * \param [IN] obj Structure containing the timer object parameters 73 | */ 74 | void TimerReset( TimerEvent_t *obj ); 75 | 76 | /*! 77 | * \brief Set timer new timeout value 78 | * 79 | * \param [IN] obj Structure containing the timer object parameters 80 | * \param [IN] value New timer timeout value 81 | */ 82 | void TimerSetValue( TimerEvent_t *obj, uint32_t value ); 83 | 84 | /*! 85 | * \brief Read the current time 86 | * 87 | * \retval time returns current time 88 | */ 89 | TimerTime_t TimerGetCurrentTime( void ); 90 | 91 | /*! 92 | * \brief Return the Time elapsed since a fix moment in Time 93 | * 94 | * \param [IN] savedTime fix moment in Time 95 | * \retval time returns elapsed time 96 | */ 97 | TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime ); 98 | 99 | /*! 100 | * \brief Return the Time elapsed since a fix moment in Time 101 | * 102 | * \param [IN] eventInFuture fix moment in the future 103 | * \retval time returns difference between now and future event 104 | */ 105 | TimerTime_t TimerGetFutureTime( TimerTime_t eventInFuture ); 106 | 107 | /*! 108 | * \brief Manages the entry into ARM cortex deep-sleep mode 109 | */ 110 | void TimerLowPowerHandler( void ); 111 | void IRAM_ATTR TimerIrqHandler( void ); 112 | 113 | #ifdef __cplusplus 114 | } // extern "C" 115 | #endif 116 | 117 | 118 | #endif // __TIMER_H__ 119 | -------------------------------------------------------------------------------- /src/utilities.c: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Helper functions implementation 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #include 16 | #include 17 | #include "board.h" 18 | //#include "utilities.h" 19 | 20 | /*! 21 | * Redefinition of rand() and srand() standard C functions. 22 | * These functions are redefined in order to get the same behavior across 23 | * different compiler toolchains implementations. 24 | */ 25 | // Standard random functions redefinition start 26 | #define RAND_LOCAL_MAX 2147483647L 27 | 28 | static uint32_t next = 1; 29 | 30 | int32_t rand1( void ) 31 | { 32 | return ( ( next = next * 1103515245L + 12345L ) % RAND_LOCAL_MAX ); 33 | } 34 | 35 | void srand1( uint32_t seed ) 36 | { 37 | next = seed; 38 | } 39 | // Standard random functions redefinition end 40 | 41 | int32_t randr( int32_t min, int32_t max ) 42 | { 43 | return ( int32_t )rand1( ) % ( max - min + 1 ) + min; 44 | } 45 | 46 | void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size ) 47 | { 48 | while( size-- ) 49 | { 50 | *dst++ = *src++; 51 | } 52 | } 53 | 54 | void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size ) 55 | { 56 | dst = dst + ( size - 1 ); 57 | while( size-- ) 58 | { 59 | *dst-- = *src++; 60 | } 61 | } 62 | 63 | void memset1( uint8_t *dst, uint8_t value, uint16_t size ) 64 | { 65 | while( size-- ) 66 | { 67 | *dst++ = value; 68 | } 69 | } 70 | 71 | int8_t Nibble2HexChar( uint8_t a ) 72 | { 73 | if( a < 10 ) 74 | { 75 | return '0' + a; 76 | } 77 | else if( a < 16 ) 78 | { 79 | return 'A' + ( a - 10 ); 80 | } 81 | else 82 | { 83 | return '?'; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/utilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | / _____) _ | | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ 5 | _____) ) ____| | | || |_| ____( (___| | | | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| 7 | (C)2013 Semtech 8 | 9 | Description: Helper functions implementation 10 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project 12 | 13 | Maintainer: Miguel Luis and Gregory Cristian 14 | */ 15 | #ifndef __UTILITIES_H__ 16 | #define __UTILITIES_H__ 17 | #include 18 | 19 | #ifdef __cplusplus 20 | extern "C"{ 21 | #endif 22 | 23 | /*! 24 | * \brief Returns the minimum value between a and b 25 | * 26 | * \param [IN] a 1st value 27 | * \param [IN] b 2nd value 28 | * \retval minValue Minimum value 29 | */ 30 | #define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) 31 | 32 | /*! 33 | * \brief Returns the maximum value between a and b 34 | * 35 | * \param [IN] a 1st value 36 | * \param [IN] b 2nd value 37 | * \retval maxValue Maximum value 38 | */ 39 | #define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) 40 | 41 | /*! 42 | * \brief Returns 2 raised to the power of n 43 | * 44 | * \param [IN] n power value 45 | * \retval result of raising 2 to the power n 46 | */ 47 | #define POW2( n ) ( 1 << n ) 48 | 49 | /*! 50 | * \brief Initializes the pseudo random generator initial value 51 | * 52 | * \param [IN] seed Pseudo random generator initial value 53 | */ 54 | void srand1( uint32_t seed ); 55 | 56 | /*! 57 | * \brief Computes a random number between min and max 58 | * 59 | * \param [IN] min range minimum value 60 | * \param [IN] max range maximum value 61 | * \retval random random value in range min..max 62 | */ 63 | int32_t randr( int32_t min, int32_t max ); 64 | 65 | /*! 66 | * \brief Copies size elements of src array to dst array 67 | * 68 | * \remark STM32 Standard memcpy function only works on pointers that are aligned 69 | * 70 | * \param [OUT] dst Destination array 71 | * \param [IN] src Source array 72 | * \param [IN] size Number of bytes to be copied 73 | */ 74 | void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size ); 75 | 76 | /*! 77 | * \brief Copies size elements of src array to dst array reversing the byte order 78 | * 79 | * \param [OUT] dst Destination array 80 | * \param [IN] src Source array 81 | * \param [IN] size Number of bytes to be copied 82 | */ 83 | void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size ); 84 | 85 | /*! 86 | * \brief Set size elements of dst array with value 87 | * 88 | * \remark STM32 Standard memset function only works on pointers that are aligned 89 | * 90 | * \param [OUT] dst Destination array 91 | * \param [IN] value Default value 92 | * \param [IN] size Number of bytes to be copied 93 | */ 94 | void memset1( uint8_t *dst, uint8_t value, uint16_t size ); 95 | 96 | /*! 97 | * \brief Converts a nibble to an hexadecimal character 98 | * 99 | * \param [IN] a Nibble to be converted 100 | * \retval hexChar Converted hexadecimal character 101 | */ 102 | int8_t Nibble2HexChar( uint8_t a ); 103 | 104 | 105 | #ifdef __cplusplus 106 | } // extern "C" 107 | #endif 108 | 109 | #endif // __UTILITIES_H__ 110 | --------------------------------------------------------------------------------