Skip to content

Commit

Permalink
1.feat:first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
SeeedWenzy committed Dec 1, 2023
1 parent f5e4563 commit 0d5ca9c
Show file tree
Hide file tree
Showing 6 changed files with 441 additions and 0 deletions.
74 changes: 74 additions & 0 deletions examples/Full_Almanac_Update/Full_Almanac_Update.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <Arduino.h>

// #include <WM1110_Geolocation.hpp>
#include <LbmWm1110.hpp>
#include <Lbmx.hpp>
#include <WM1110_Almanac_Update.hpp>

/*
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);
}

////////////////////////////////////////////////////////////////////////////////
10 changes: 10 additions & 0 deletions library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name=WM1110 almanac update
version=0.0.1
author=SeeedWenzy
maintainer=SeeedWenzy <zhiyi.wen@seeed.cc>
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
185 changes: 185 additions & 0 deletions src/WM1110_Almanac_Update.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#include "WM1110_Almanac_Update.hpp"

#include <LbmWm1110.hpp>
#include <Lbmx.hpp>

#include <Lbm_Modem_Common.hpp>

#include "common/smtc_board/smtc_board.h"
#include "common/apps_modem_common.h"
#include "common/apps_modem_event.h"

#include <lbm/smtc_modem_api/smtc_modem_utilities.h>
#include <lbm/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_types.h>
#include <lbm/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss_types.h>
#include <lbm/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss.h>
#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;




60 changes: 60 additions & 0 deletions src/WM1110_Almanac_Update.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef _WM1110_ALMANAC_UPDATE_H_
#define _WM1110_ALMANAC_UPDATE_H_

#pragma once

#include <cstdio>
#include <cstdlib>
#include <bluefruit.h>

#include <Lbm_Modem_Common.hpp>


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_ */



Loading

0 comments on commit 0d5ca9c

Please sign in to comment.