diff --git a/examples/Full_Almanac_Update/Full_Almanac_Update.ino b/examples/Full_Almanac_Update/Full_Almanac_Update.ino new file mode 100644 index 0000000..44d489c --- /dev/null +++ b/examples/Full_Almanac_Update/Full_Almanac_Update.ino @@ -0,0 +1,74 @@ +#include + +// #include +#include +#include +#include + +/* + tips: + 1.Make sure the almanac.h files are up to date,if not,please update it. + 2.Note that the updated almanac in the almanac.h file are not necessarily newer than the almanac stored on the chip +*/ + + +static LbmWm1110& lbmWm1110 = LbmWm1110::getInstance(); + +// MyLbmxEventHandlers +class MyLbmxEventHandlers : public LbmxEventHandlers +{ +protected: + void reset(const LbmxEvent& event) override; + +}; + +void MyLbmxEventHandlers::reset(const LbmxEvent& event) +{ + +} + +static void ModemEventHandler() +{ + static LbmxEvent event; + static MyLbmxEventHandlers handlers; + + while (event.fetch()) + { + printf("----- %s -----\n", event.getEventString().c_str()); + + handlers.invoke(event); + } +} +uint32_t local_almanac_date = 0; +uint32_t stored_almanac_date = 0; +void setup() +{ + Serial.begin(115200); + while (!Serial) delay(100); + + printf("WM1110 Almanac Update Example\r\n"); + + lbmWm1110.begin(); + + LbmxEngine::begin(lbmWm1110.getRadio(), ModemEventHandler); + + wm1110_almanac_update.updateStoredAlmanac(); + + local_almanac_date = wm1110_almanac_update.getFullAlmanacDateTime(); + stored_almanac_date = wm1110_almanac_update.getStoredAlmanacDateTime(); +} + +void loop() +{ + if(local_almanac_date != stored_almanac_date) + { + printf("Update WM1110 almanac fail\r\n"); + } + else + { + printf("Update WM1110 almanac success,almanac date:%u\r\n",local_almanac_date); + } + delay(1000); +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..4edfa34 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=WM1110 almanac update +version=0.0.1 +author=SeeedWenzy +maintainer=SeeedWenzy +sentence=A library for updating the almanac of WM1110 +paragraph=A library for updating the almanac of WM1110 +category=Device Control +url=https://github.com/Seeed-Studio/ +architectures=nrf52 +includes=WM1110_Almanac_Update.hpp diff --git a/src/WM1110_Almanac_Update.cpp b/src/WM1110_Almanac_Update.cpp new file mode 100644 index 0000000..e847f31 --- /dev/null +++ b/src/WM1110_Almanac_Update.cpp @@ -0,0 +1,185 @@ +#include "WM1110_Almanac_Update.hpp" + +#include +#include + +#include + +#include "common/smtc_board/smtc_board.h" +#include "common/apps_modem_common.h" +#include "common/apps_modem_event.h" + +#include +#include +#include +#include +#include "almanac.h" + + +#define OFFSET_BETWEEN_GPS_EPOCH_AND_UNIX_EPOCH 315964800 + +lr11xx_gnss_almanac_full_read_bytestream_t lr11xx_almanac; + +static LbmWm1110& lbmWm1110 = LbmWm1110::getInstance(); +ralf_t* modem_radio = lbmWm1110.getRadio(); + + +WM1110_Almanac_Update* WM1110_Almanac_Update::instance_ = nullptr; + + +#if 1 // public function +WM1110_Almanac_Update& WM1110_Almanac_Update::getInstance() +{ + if (instance_ == nullptr) + { + instance_ = new WM1110_Almanac_Update(); + } + + return *instance_; +} + +WM1110_Almanac_Update::WM1110_Almanac_Update(void) +{ + +} + +void WM1110_Almanac_Update::begin( void ) +{ + +} + +void WM1110_Almanac_Update::updateStoredAlmanac( void ) +{ + uint32_t almanac_date = getStoredAlmanacDateTime( ); + full_almanac_date_time = getFullAlmanacDateTime(); + printf("LR11XX almanac date: %u, Local almanac date: %u\r\n", almanac_date, full_almanac_date_time ); + + if( almanac_date < full_almanac_date_time ) + { + bool ret = almanac_update( modem_radio->ral.context, full_almanac, sizeof( full_almanac )); + } + else if(almanac_date > full_almanac_date_time) + { + printf("Please run get_full_almanac.py to update full almanac buffer firstly\r\n"); + } + else + { + printf( "Local almanac matches LR11XX almanac -> no update\n" ); + } +} + +uint32_t WM1110_Almanac_Update::getStoredAlmanacDateTime( void ) +{ + if( lr11xx_gnss_read_almanac( modem_radio->ral.context , lr11xx_almanac ) == LR11XX_STATUS_OK ) + { + // printf( "almanac_date_raw: %02x%02x, %02x%02x\r\n", lr11xx_almanac[2], lr11xx_almanac[1], lr11xx_almanac[24], lr11xx_almanac[23] ); + // uint16_t almanac_date_raw = ( uint16_t )( ( lr11xx_almanac[2] << 8 ) | lr11xx_almanac[1] ); + uint16_t almanac_date_raw = ( uint16_t )( ( lr11xx_almanac[24] << 8 ) | lr11xx_almanac[23] ); + uint32_t almanac_date = ( OFFSET_BETWEEN_GPS_EPOCH_AND_UNIX_EPOCH + 24 * 3600 * ( 2048 * 7 + almanac_date_raw ) ); + return almanac_date; + } + else + { + return 0; + } +} + +bool WM1110_Almanac_Update::get_almanac_crc( const void* ral_context, uint32_t* almanac_crc ) +{ + lr11xx_status_t err; + lr11xx_gnss_context_status_bytestream_t context_status_bytestream; + lr11xx_gnss_context_status_t context_status; + + err = lr11xx_gnss_get_context_status( ral_context, context_status_bytestream ); + if( err != LR11XX_STATUS_OK ) + { + printf( "Failed to get gnss context status\n" ); + return false; + } + + err = lr11xx_gnss_parse_context_status_buffer( context_status_bytestream, &context_status ); + if( err != LR11XX_STATUS_OK ) + { + printf( "Failed to parse gnss context status to get almanac status\n" ); + return false; + } + + *almanac_crc = context_status.global_almanac_crc; + + return true; +} + +#endif + + +#if 1 // private function +bool WM1110_Almanac_Update::almanac_update( const void* ral_context, uint8_t *almanac_data, uint16_t almanac_len ) +{ + uint32_t global_almanac_crc, local_almanac_crc; + local_almanac_crc = ( almanac_data[6] << 24 ) + ( almanac_data[5] << 16 ) + ( almanac_data[4] << 8 ) + ( almanac_data[3] ); + + if( get_almanac_crc( ral_context, &global_almanac_crc ) == false ) + { + printf( "Failed to get almanac CRC before update\n" ); + return false; + } + if( global_almanac_crc != local_almanac_crc ) + { + printf( "Local almanac doesn't match LR11XX almanac -> start update\n" ); + + /* Load almanac in flash */ + uint16_t almanac_idx = 0; + while( almanac_idx < almanac_len ) + { + if( lr11xx_gnss_almanac_update( ral_context, almanac_data + almanac_idx, 1 ) != LR11XX_STATUS_OK ) + { + printf( "Failed to update almanac\n" ); + return false; + } + almanac_idx += LR11XX_GNSS_SINGLE_ALMANAC_WRITE_SIZE; + } + + /* Check CRC again to confirm proper update */ + if( get_almanac_crc( ral_context, &global_almanac_crc ) == false ) + { + printf( "Failed to get almanac CRC after update\n" ); + return false; + } + if( global_almanac_crc != local_almanac_crc ) + { + printf( "0x%08x, 0x%08x\r\n", global_almanac_crc, local_almanac_crc ); + printf( "Local almanac doesn't match LR11XX almanac -> update failed\n" ); + return false; + } + else + { + uint32_t almanac_date = getStoredAlmanacDateTime( ); + printf("LR11XX new almanac date: %u\r\n", almanac_date ); + printf( "Almanac update succeeded\r\n" ); + } + } + else + { + printf( "Local almanac matches LR11XX almanac -> no update\n" ); + } + + return true; +} + +uint32_t WM1110_Almanac_Update::getFullAlmanacDateTime( void ) +{ + //current + uint16_t almanac_date_raw = ( uint16_t )( ( full_almanac[2] << 8 ) | full_almanac[1] ); + uint32_t almanac_date = ( OFFSET_BETWEEN_GPS_EPOCH_AND_UNIX_EPOCH + 24 * 3600 * ( 2048 * 7 + almanac_date_raw ) ); + + full_almanac_date_time = almanac_date; + return full_almanac_date_time; +} + +#endif + +WM1110_Almanac_Update wm1110_almanac_update; + + + + diff --git a/src/WM1110_Almanac_Update.hpp b/src/WM1110_Almanac_Update.hpp new file mode 100644 index 0000000..81548b7 --- /dev/null +++ b/src/WM1110_Almanac_Update.hpp @@ -0,0 +1,60 @@ +#ifndef _WM1110_ALMANAC_UPDATE_H_ +#define _WM1110_ALMANAC_UPDATE_H_ + +#pragma once + +#include +#include +#include + +#include + + +class WM1110_Almanac_Update +{ + private: + static WM1110_Almanac_Update* instance_; + + uint32_t full_almanac_date_time; + uint32_t stored_almanac_date_time; + + public: + WM1110_Almanac_Update(void); + + static WM1110_Almanac_Update& getInstance(); + + void begin( void ); + + /*! + * @brief Updata WM1110 almanac + */ + void updateStoredAlmanac( void ); + + /*! + * @brief Get current almanac date time that Stored in WM1110 + * @return timestamp + */ + uint32_t getStoredAlmanacDateTime( void ); + + /*! + * @brief Get full almanac date time from full_almanac(almanac.h) + * @return timestamp + */ + uint32_t getFullAlmanacDateTime( void ); + + private: + + bool get_almanac_crc( const void* ral_context, uint32_t* almanac_crc ); + + bool almanac_update( const void* ral_context, uint8_t *almanac_data, uint16_t almanac_len ); + + public: + +}; + +extern WM1110_Almanac_Update wm1110_almanac_update; + +#endif /* _WM1110_ALMANAC_UPDATE_H_ */ + + + diff --git a/src/almanac.h b/src/almanac.h new file mode 100644 index 0000000..1e46514 --- /dev/null +++ b/src/almanac.h @@ -0,0 +1,5 @@ +/* This file has been auto-generated by the get_full_almanac.py script */ + +#include "lbm/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss.h" + +static uint8_t full_almanac[( LR11XX_GNSS_FULL_UPDATE_N_ALMANACS * LR11XX_GNSS_SINGLE_ALMANAC_WRITE_SIZE ) + 20] = { 0x80, 0x90, 0x06, 0xC6, 0xBF, 0x10, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x5D, 0x43, 0x28, 0x24, 0x04, 0x6D, 0x27, 0x9F, 0x2E, 0x5F, 0xCA, 0xFC, 0xDD, 0xA6, 0xFF, 0x6F, 0x00, 0x01, 0x00, 0x02, 0x0B, 0x43, 0x28, 0x4C, 0x01, 0xFF, 0x27, 0xB2, 0x93, 0x80, 0x2D, 0x10, 0x0C, 0xAE, 0xFF, 0x37, 0x00, 0x01, 0x00, 0x03, 0x15, 0x43, 0x28, 0xB0, 0x00, 0x3E, 0x27, 0x66, 0x0F, 0x63, 0x83, 0x11, 0x38, 0xA6, 0xFF, 0x1B, 0x00, 0x01, 0x00, 0x04, 0x6A, 0x43, 0x28, 0x82, 0x01, 0x78, 0x27, 0xF8, 0x27, 0x88, 0x32, 0x13, 0x0A, 0xAA, 0xFF, 0xA4, 0x01, 0x01, 0x00, 0x05, 0x79, 0x43, 0x28, 0xC2, 0x00, 0x53, 0x28, 0x99, 0xCB, 0x39, 0xDE, 0xD0, 0xE1, 0xAC, 0xFF, 0xD2, 0x00, 0x01, 0x00, 0x06, 0x4E, 0x43, 0x28, 0x84, 0x04, 0xB9, 0x26, 0x40, 0xA6, 0xB9, 0xA7, 0x65, 0x61, 0xAC, 0xFF, 0xA6, 0x01, 0x01, 0x00, 0x07, 0x6D, 0x43, 0x28, 0x46, 0x02, 0xF3, 0x26, 0x7C, 0x19, 0x3E, 0x0B, 0x6F, 0xB5, 0xA0, 0xFF, 0xD3, 0x00, 0x01, 0x00, 0x08, 0x6A, 0x43, 0x28, 0xC3, 0x00, 0xFA, 0x26, 0xDD, 0x2E, 0x9B, 0x50, 0xB4, 0x35, 0xA4, 0xFF, 0x69, 0x00, 0x01, 0x00, 0x09, 0x4A, 0x43, 0x28, 0x53, 0x02, 0xFC, 0x27, 0x6A, 0x6D, 0x03, 0x9D, 0xF5, 0x0B, 0xAE, 0xFF, 0xBB, 0x00, 0x01, 0x00, 0x0A, 0x29, 0x43, 0x28, 0x53, 0x00, 0x5D, 0x27, 0x93, 0xFD, 0xDC, 0x95, 0x57, 0xE3, 0xAA, 0xFF, 0x5D, 0x00, 0x01, 0x00, 0x0B, 0x6F, 0x43, 0x28, 0x3A, 0x02, 0x4B, 0x27, 0x37, 0x8B, 0xCB, 0x38, 0xD0, 0x8E, 0xA9, 0xFF, 0x17, 0x00, 0x01, 0x00, 0x0C, 0x31, 0x43, 0x28, 0xF8, 0x01, 0x85, 0x27, 0x03, 0x0C, 0xDF, 0x26, 0x58, 0x3C, 0xA5, 0xFF, 0x0B, 0x00, 0x01, 0x00, 0x0D, 0x41, 0x43, 0x28, 0xF0, 0x00, 0x9D, 0x26, 0xB9, 0x88, 0xDE, 0x87, 0x21, 0x8D, 0xA5, 0xFF, 0x05, 0x00, 0x01, 0x00, 0x0E, 0xFD, 0x42, 0x28, 0xF6, 0x03, 0x06, 0x26, 0xCA, 0xEF, 0xD0, 0x33, 0xB3, 0x30, 0xA2, 0xFF, 0x02, 0x00, 0x01, 0x00, 0x0F, 0x49, 0x43, 0x28, 0x7D, 0x03, 0x46, 0x27, 0x2B, 0x43, 0x9B, 0x20, 0x8C, 0x8F, 0xA6, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x10, 0x1A, 0x43, 0x28, 0x8B, 0x03, 0x96, 0x27, 0xDE, 0x1B, 0xDB, 0xC7, 0x2B, 0xB9, 0xA0, 0xFF, 0x91, 0x01, 0x01, 0x00, 0x11, 0x35, 0x43, 0x28, 0xFB, 0x00, 0xB4, 0x27, 0x9D, 0xC6, 0xD7, 0x83, 0x18, 0xE2, 0xAB, 0xFF, 0xC8, 0x00, 0x01, 0x00, 0x12, 0x35, 0x43, 0x28, 0x65, 0x02, 0x8D, 0x27, 0x99, 0x6F, 0x9A, 0x63, 0xFB, 0xBA, 0xA4, 0xFF, 0x64, 0x00, 0x01, 0x00, 0x13, 0x33, 0x43, 0x28, 0x0D, 0x01, 0xC2, 0x26, 0x0C, 0xE4, 0xE9, 0x8E, 0xF8, 0x04, 0xA9, 0xFF, 0x32, 0x00, 0x01, 0x00, 0x14, 0x68, 0x43, 0x28, 0x5E, 0x06, 0x31, 0x27, 0x16, 0x1B, 0x19, 0xE4, 0xBE, 0xDD, 0xA5, 0xFF, 0x19, 0x00, 0x01, 0x00, 0x15, 0x5E, 0x43, 0x28, 0xDB, 0x03, 0x3F, 0x27, 0x3D, 0x32, 0x79, 0xD0, 0xAF, 0x8F, 0xAB, 0xFF, 0x0C, 0x00, 0x01, 0x00, 0x16, 0x4B, 0x43, 0x28, 0xFD, 0x00, 0xCA, 0x27, 0xBC, 0x9D, 0xF4, 0x83, 0xD1, 0x0A, 0xAD, 0xFF, 0xCC, 0x01, 0x01, 0x00, 0x17, 0x23, 0x43, 0x28, 0xCD, 0x03, 0x0D, 0x26, 0x83, 0xD0, 0x57, 0x26, 0x95, 0x5D, 0xA3, 0xFF, 0x39, 0x00, 0x01, 0x00, 0x18, 0x38, 0x43, 0x28, 0xEC, 0x02, 0xCC, 0x26, 0xEB, 0x83, 0xFA, 0x2A, 0x61, 0x8B, 0xA9, 0xFF, 0x1C, 0x00, 0x01, 0x00, 0x19, 0x77, 0x43, 0x28, 0x2E, 0x02, 0x04, 0x26, 0xF7, 0x63, 0xFE, 0x13, 0xFC, 0x88, 0xA6, 0xFF, 0x0E, 0x00, 0x01, 0x00, 0x1A, 0x37, 0x43, 0x28, 0x06, 0x03, 0x50, 0x27, 0x3A, 0x1E, 0x34, 0x1E, 0x71, 0xB6, 0xA1, 0xFF, 0x07, 0x00, 0x01, 0x00, 0x1B, 0x77, 0x43, 0x28, 0x33, 0x00, 0x2D, 0x27, 0x96, 0x6E, 0x48, 0x3F, 0xF4, 0x5F, 0xAA, 0xFF, 0x03, 0x00, 0x01, 0x00, 0x1C, 0x43, 0x43, 0x28, 0xA5, 0x00, 0xAE, 0x27, 0xFD, 0x16, 0xD7, 0x68, 0xC3, 0xB9, 0xA4, 0xFF, 0xA8, 0x01, 0x01, 0x00, 0x1D, 0x5D, 0x43, 0x28, 0xB0, 0x01, 0x1E, 0x26, 0x9B, 0xA2, 0x03, 0x98, 0x8B, 0x61, 0xA8, 0xFF, 0xD4, 0x00, 0x01, 0x00, 0x1E, 0x33, 0x43, 0x28, 0xB7, 0x02, 0xE3, 0x26, 0xC7, 0x83, 0x4B, 0x19, 0x3D, 0x62, 0xAB, 0xFF, 0x6A, 0x00, 0x01, 0x00, 0x1F, 0x0F, 0x43, 0x28, 0xD2, 0x01, 0x1F, 0x27, 0x18, 0x38, 0x66, 0xA5, 0x44, 0x36, 0xA4, 0xFF, 0x35, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0xCA, 0xB9, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x66, 0x00, 0x00, 0x87, 0x01, 0x02, 0x01, 0x41, 0xEF, 0xBE, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x3B, 0x00, 0x00, 0x39, 0x06, 0x02, 0x01, 0x42, 0x1A, 0xC1, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x4E, 0x00, 0x00, 0xE6, 0x01, 0x02, 0x01, 0x43, 0x60, 0xB7, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x71, 0x00, 0x00, 0x09, 0x06, 0x02, 0x01, 0x44, 0xDD, 0xC0, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x29, 0x00, 0x00, 0x05, 0x06, 0x02, 0x01, 0x45, 0xE6, 0xB9, 0x32, 0xF6, 0x00, 0x8E, 0x26, 0x89, 0x6F, 0x8C, 0x86, 0xE1, 0x55, 0xE9, 0xFF, 0xF8, 0x01, 0x02, 0x01, 0x46, 0x36, 0xBB, 0x32, 0xC3, 0x00, 0x0C, 0x23, 0xAA, 0x0F, 0x62, 0x97, 0x6E, 0xA5, 0xDD, 0xFF, 0x06, 0x06, 0x02, 0x01, 0x47, 0x4A, 0xBB, 0x32, 0xBA, 0x00, 0x6F, 0x2B, 0xF8, 0xCE, 0x68, 0x7E, 0xE3, 0xFE, 0xF3, 0xFF, 0xF9, 0x01, 0x02, 0x01, 0x48, 0x41, 0xBB, 0x32, 0xDA, 0x02, 0xC0, 0x26, 0xAE, 0x49, 0x51, 0xA1, 0xB2, 0x57, 0xE9, 0xFF, 0x04, 0x07, 0x02, 0x01, 0x49, 0x67, 0xBB, 0x32, 0x5E, 0x02, 0x23, 0x23, 0x3B, 0x00, 0x22, 0x9D, 0x32, 0xA5, 0xDD, 0xFF, 0xBE, 0x07, 0x02, 0x01, 0x4A, 0x2E, 0x45, 0x29, 0x98, 0x00, 0x25, 0x28, 0x4A, 0x69, 0x65, 0xB8, 0x3F, 0xCB, 0xB4, 0xFF, 0x61, 0x00, 0x02, 0x01, 0x4B, 0x28, 0x45, 0x29, 0x5C, 0x00, 0x15, 0x28, 0x1B, 0x89, 0x7A, 0xB9, 0xBD, 0xCA, 0xB4, 0xFF, 0x8E, 0x07, 0x02, 0x01, 0x4C, 0x0B, 0xBB, 0x32, 0x40, 0x01, 0xE2, 0x29, 0xD9, 0xAA, 0x04, 0x9C, 0xB5, 0xFD, 0xF2, 0xFF, 0x82, 0x07, 0x02, 0x01, 0x4D, 0x27, 0x45, 0x29, 0x40, 0x00, 0xA2, 0x27, 0x74, 0xD5, 0xAA, 0xF7, 0x0A, 0x1F, 0xB6, 0xFF, 0x7F, 0x00, 0x02, 0x01, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4F, 0x1F, 0xBB, 0x32, 0x9B, 0x01, 0x2F, 0x27, 0x12, 0x58, 0xA1, 0xA2, 0xAC, 0x55, 0xEA, 0xFF, 0x7E, 0x00, 0x02, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x52, 0x24, 0x45, 0x29, 0x24, 0x00, 0xBD, 0x27, 0xAE, 0x66, 0xDA, 0xD5, 0x16, 0x1F, 0xB7, 0xFF, 0x3C, 0x00, 0x02, 0x01, 0x53, 0x24, 0x45, 0x29, 0x1C, 0x00, 0xBD, 0x27, 0x60, 0x62, 0x4B, 0xF8, 0x1D, 0x1F, 0xB6, 0xFF, 0xC1, 0x07, 0x02, 0x01, 0x54, 0x26, 0x45, 0x29, 0x18, 0x00, 0xB6, 0x27, 0xEB, 0x12, 0x6D, 0xE9, 0x29, 0x1F, 0xB6, 0xFF, 0x3F, 0x00, 0x02, 0x01, 0x55, 0x25, 0x45, 0x29, 0x1E, 0x00, 0xB6, 0x27, 0xF4, 0xFD, 0x35, 0x1E, 0x28, 0x1F, 0xB7, 0xFF, 0xC0, 0x07, 0x02, 0x01, 0x56, 0x28, 0x45, 0x29, 0x0D, 0x00, 0x89, 0x26, 0x99, 0x4E, 0x05, 0xFC, 0x76, 0x74, 0xB7, 0xFF, 0xEF, 0x07, 0x02, 0x01, 0x57, 0x32, 0x45, 0x29, 0x32, 0x00, 0x89, 0x26, 0x3A, 0x6F, 0xFC, 0x1A, 0x74, 0x74, 0xB7, 0xFF, 0xE3, 0x07, 0x02, 0x01, 0x58, 0x2C, 0x45, 0x29, 0x26, 0x00, 0x98, 0x26, 0xE4, 0x4E, 0x2C, 0x1A, 0x7B, 0x73, 0xB7, 0xFF, 0x1E, 0x00, 0x02, 0x01, 0x59, 0x29, 0x45, 0x29, 0x3B, 0x00, 0x99, 0x26, 0x7F, 0x8F, 0x63, 0x19, 0x81, 0x73, 0xB7, 0xFF, 0xE0, 0x07, 0x02, 0x01, 0x5A, 0x21, 0x45, 0x29, 0x1E, 0x00, 0x27, 0x27, 0xD8, 0x9D, 0xC7, 0x33, 0x33, 0xCA, 0xB1, 0xFF, 0x1F, 0x00, 0x02, 0x01, 0x5B, 0x28, 0x45, 0x29, 0x12, 0x00, 0x26, 0x27, 0xAA, 0x3D, 0x25, 0xB1, 0x31, 0xCA, 0xB2, 0xFF, 0x0C, 0x00, 0x02, 0x01, 0x5C, 0x1F, 0x45, 0x29, 0x03, 0x00, 0x13, 0x27, 0x80, 0x25, 0xBA, 0x6C, 0x95, 0xC8, 0xB0, 0xFF, 0xF1, 0x07, 0x02, 0x01, 0x5D, 0x1F, 0x45, 0x29, 0x17, 0x00, 0x13, 0x27, 0x52, 0xA9, 0x52, 0x0A, 0x9B, 0xC8, 0xB0, 0xFF, 0x0F, 0x00, 0x02, 0x01, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5F, 0x23, 0x45, 0x29, 0x0F, 0x00, 0xB0, 0x27, 0xA9, 0xAB, 0xE6, 0xD0, 0xD4, 0x1E, 0xB5, 0xFF, 0xFD, 0x07, 0x02, 0x01, 0x60, 0x26, 0x45, 0x29, 0x0D, 0x00, 0xB1, 0x27, 0x61, 0xA3, 0x5A, 0x19, 0xD2, 0x1E, 0xB6, 0xFF, 0x03, 0x00, 0x02, 0x01, 0x61, 0x22, 0x45, 0x29, 0x1A, 0x00, 0x00, 0x27, 0xF4, 0x19, 0x21, 0x17, 0xAB, 0xC8, 0xB0, 0xFF, 0xFC, 0x07, 0x02, 0x01, 0x62, 0x22, 0x45, 0x29, 0x2C, 0x00, 0x01, 0x27, 0x93, 0x61, 0x0B, 0x0D, 0xAB, 0xC8, 0xB1, 0xFF, 0xFE, 0x07, 0x02, 0x01, 0x63, 0x26, 0x45, 0x29, 0x28, 0x00, 0x98, 0x26, 0x4E, 0x17, 0x41, 0xD3, 0x68, 0x74, 0xB7, 0xFF, 0x01, 0x00, 0x02, 0x01, 0x64, 0x33, 0x45, 0x29, 0x29, 0x00, 0x98, 0x26, 0x8D, 0x38, 0x8F, 0xF1, 0x67, 0x74, 0xB7, 0xFF, 0xFF, 0x07, 0x02, 0x01, 0x65, 0x5E, 0xBB, 0x32, 0x9F, 0x00, 0xCA, 0x28, 0x0E, 0xCB, 0xBD, 0x8B, 0xAC, 0xFD, 0xF1, 0xFF, 0x57, 0x04, 0x02, 0x01, 0x66, 0x83, 0xBB, 0x32, 0xD6, 0x00, 0x34, 0x27, 0xEA, 0x77, 0xA6, 0x88, 0xC7, 0x52, 0xEA, 0xFF, 0xED, 0x04, 0x02, 0x01, 0x67, 0x38, 0xBB, 0x32, 0xDD, 0x00, 0x1C, 0x28, 0xAD, 0x23, 0x1B, 0x86, 0xD0, 0xAA, 0xDF, 0xFF, 0xDD, 0x04, 0x02, 0x01, 0x68, 0x22, 0x45, 0x29, 0x59, 0x00, 0xA4, 0x27, 0xD6, 0xDB, 0xAA, 0xC1, 0xF5, 0x1E, 0xB5, 0xFF, 0xD1, 0x04, 0x02, 0x01, 0x69, 0x25, 0x45, 0x29, 0x4A, 0x00, 0xA5, 0x27, 0x80, 0x0F, 0xD9, 0xCD, 0xFB, 0x1E, 0xB5, 0xFF, 0xD2, 0x04, 0x02, 0x01, 0x6A, 0x21, 0x45, 0x29, 0x19, 0x00, 0xE0, 0x26, 0xA1, 0x02, 0x28, 0x11, 0xA0, 0xC8, 0xB0, 0xFF, 0x2D, 0x03, 0x02, 0x01, 0x6B, 0x21, 0x45, 0x29, 0x27, 0x00, 0xE5, 0x26, 0xFE, 0x3E, 0xF7, 0x12, 0xA3, 0xC8, 0xB0, 0xFF, 0x8C, 0x04, 0x02, 0x01, 0x6C, 0x2A, 0x45, 0x29, 0x26, 0x00, 0xC1, 0x26, 0x0F, 0xC0, 0x91, 0x09, 0x8F, 0x74, 0xB7, 0xFF, 0x92, 0x04, 0x02, 0x01, 0x6D, 0x2C, 0x45, 0x29, 0x3B, 0x00, 0xC2, 0x26, 0xDE, 0xFE, 0x5A, 0x09, 0x94, 0x74, 0xB8, 0xFF, 0xBC, 0x04, 0x02, 0x01, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7A, 0x2F, 0xBB, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x63, 0x00, 0x00, 0x3B, 0x05, 0x02, 0x01, 0x7B, 0xC9, 0xBC, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0x38, 0x00, 0x00, 0x37, 0x05, 0x02, 0x01, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 }; diff --git a/src/get_full_almanac.py b/src/get_full_almanac.py new file mode 100644 index 0000000..2dd8260 --- /dev/null +++ b/src/get_full_almanac.py @@ -0,0 +1,107 @@ +""" +The Clear BSD License +Copyright Semtech Corporation 2021. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted (subject to the limitations in the disclaimer +below) provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Semtech corporation nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY +THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +import base64 +import requests + +import sys +from argparse import ArgumentParser + +# refer to https://github.com/Lora-net/SWSD004/blob/master/apps/examples/full_almanac_update/get_full_almanac.py +# mgs_token : +# filename: almanac.h +# Command example: +# python .\get_full_almanac.py -f almanac.h mgs_token + +OFFSET_BETWEEN_GPS_EPOCH_AND_UNIX_EPOCH = 315964800 + +def main(): + + # The file in which the almanac will be written to + filename_default = "almanac.h" + parser = ArgumentParser( + description="Companion software that generates almanac header file to be compiled for LR1110/LR1120 embedded full almanac update." + ) + parser.add_argument( + "mgs_token", help="MGS LoRa Cloud token to use to fetch the almanac" + ) + parser.add_argument( + "-f", + "--output_file", + help="file that will contain the results", + default=filename_default, + ) + args = parser.parse_args() + + mgs_token = args.mgs_token + filename = args.output_file + + # Build request URL + url = "https://mgs.loracloud.com/api/v1/almanac/full" + print("Requesting latest full almanac image available...") + + # HTTP request to MGS + my_header = {"Authorization": mgs_token} + res = requests.get(url, headers=my_header) + + if res.status_code != 200: + print("ERROR: failed to get almanac - " + str(res)) + sys.exit(2) + else: + print("Success") + print(res.json()) + print() + raw_bytes = bytes(base64.b64decode(res.json()["result"]["almanac_image"])) + + print(len(raw_bytes)) + print(raw_bytes) + # Build the byte array containing the almanac to be written to LR11xx + my_almanac_in_hex = "static uint8_t full_almanac[( LR11XX_GNSS_FULL_UPDATE_N_ALMANACS * LR11XX_GNSS_SINGLE_ALMANAC_WRITE_SIZE ) + 20] = { " + my_almanac_in_hex += ", ".join("0x{:02X}".format(byt) for byt in raw_bytes) + my_almanac_in_hex += " };" + + # Write C file to be included to the full_almanac_update application for writting to LR11xx + file_header = ( + "/* This file has been auto-generated by the get_full_almanac.py script */\n\n" + ) + file_header += '#include "lbm/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss.h"\n\n' + with open(filename, "w") as f: + f.write(file_header + my_almanac_in_hex + "\n") + + print("Almanac image written to " + filename + " file") + + almanac_date_raw = ( ( raw_bytes[2] << 8 ) | raw_bytes[1] ) + print(almanac_date_raw) + + almanac_date = ( OFFSET_BETWEEN_GPS_EPOCH_AND_UNIX_EPOCH + 24 * 3600 * ( 2048 * 7 + almanac_date_raw ) ); + print("current almanac date timestamp:",almanac_date) + +if __name__ == "__main__": + main()