element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Embedded and Microcontrollers
  • Technologies
  • More
Embedded and Microcontrollers
Blog C++ library for ST Teseo GPS - pt. 2: Dynamic GPS configuration (and some other things)
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Embedded and Microcontrollers to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 13 Jul 2024 3:50 PM Date Created
  • Views 881 views
  • Likes 7 likes
  • Comments 10 comments
  • Teseo
  • gps
  • OO
  • teseo_c++
Related
Recommended

C++ library for ST Teseo GPS - pt. 2: Dynamic GPS configuration (and some other things)

Jan Cumps
Jan Cumps
13 Jul 2024

The Teseo-LIV3 GPS module (as used in shabaz ' GPS / Galileo / BeiDou / GLONASS receiver) talks UART and I2C. I'm writing an OO driver for it, for embedded systems. In this blog, I configure the Teseo IC at runtime. And write some code guards (asserts) to validate that a (your?) project uses the library in the right way.

Initialisation

In the previous post, you had to pre-configure the Teseo-LIV3. This is advised in ST's application note for I2C communication. And if you're building a commercial device, that's the best option. A side effect is that it changes the out-of-box behaviour of the GPS. Not permanently, because it can be reverted. 

I could do this configuration programmatically, at first run. But when you are designing, or when you want top try out my library, it may be unfunny when your GPS behaves differently, and you didn't expect that. A solution is to do the configuration for the current session only, at each startup. That's what I'm developing now.

Pre-configuring the IC

The ST application note proposes this one-time configuration (text copied from the previous post):

$PSTMCFGMSGL,3,1,0,0
$PSTMSETPAR,1227,1,2
$PSTMSAVEPAR

(from the appnote:) This set of commands will:

  • Reset the i2c message list
  • Disable the eco-ing message
  • Save the configuration on flash

This will put the GPS in the right state for us at power on. If you don't mind reconfiguring the GPS (it's reversable), use this approach.

Run-time configuration

If you prefer to keep the device in its original configuration, you can use my init() functionality. Here's what it does:

  • reset the IC
  • stop the GPS engine
  • do the same configuration as in the pre-configure scenario, but don't save the settings to persistent storage
  • restart the GPS engine

Advantage:

  • once you reset or power cycle the GPS, it's back to its original state

Disadvantage:

  • it adds 4 seconds and a some ms to the startup time.
  • an additional GPIO pin is needed to control the GPS reset.

To make dynamic configuration work reliable and repeatable, the IC needs to be reset. The i2C interface is available 4 seconds later. I made this configurable. I get reliable communication when waiting4 seconds before doing business. If the IC is preconfigured, there's no wait needed and we can get to business right away.

Init functionality

Again: no need to execute this if you pre-config the device. In that case, the project should not call init().

 void teseo::init() {

    std::string s;

    resetter.call();

    // stop the engine
    write("$PSTMGPSSUSPEND\n\r");

    // reset the i2c message list
    write("$PSTMCFGMSGL,3,1,0,0\n\r");

    // disable the eco-ing message
    write("$PSTMSETPAR,1227,1,2\n\r");

    write("$PSTMGPSRESTART\n\r");
    do {
        read(s);            
    }
    while((s.find("$PSTMGPSRESTART") == std::string::npos)); // command successful 

}

The code follows the sequence described above. You can see that it requires a new callback: the resetter(). It's a simple function you'll have to provide that bumps the reset pin and waits as appropriately. I want to keep the library independent of the microcontroller that you use. So you 'll have to provide the reset function.

Here's my Pico implementation:

#define RESET_PIN (18)
#define RESET_APPLY_MS (10)
// recover must be more than 3 seconds
#define RESET_RECOVER_MS (4000)

// ...

void init () {
    // ...
    gpio_init(RESET_PIN);
    gpio_put(RESET_PIN, 1);
    gpio_set_dir(RESET_PIN, GPIO_OUT);    
}

void reset() {
    gpio_put(RESET_PIN, 0);
    sleep_ms(RESET_APPLY_MS);
    gpio_put(RESET_PIN, 1);
    sleep_ms(RESET_RECOVER_MS);
    return;
}

int main() {
    init();
    
    // ...

    gps.getResetCallback().set([]() -> void {
        reset();
    });
    
    // ...

Hardware changes

  • Connect Teseo RST Pico GP18.

Assist the developer with asserts

I'm trying to help users, by checking pre-conditions. Without increasing the final product's code size.

image

The library expects that you have your chickens in a row before you use the library. If I have to check that each time at runtime, it's going to increase the footprint of your production firmware.
That's why I use a debug-only function: asserts. Asserts are functions that will validate if something is true. At debug only. Once you build a release version of the firmware, these checks vaporise. They are ideal to catch if your code performs an action, when the object isn't properly set up. Or if you use parameters that are invalid.

I use them here to check, that you don't use functionality that needs a callback, before you registered the callback.

write:

#include <cassert>

void teseo::write(const std::string& s) {
    assert(writer.armed());
    writer.call(s);
}

read:

void teseo::read(std::string& s) {
    assert(reader.armed());
    reader.call(s);
}

init:

 void teseo::init() {
    assert(writer.armed());
    assert(reader.armed());
    assert(resetter.armed());
    
    // ...

I had to adapt my callback code to support this. I could have just put the assert inside that class. But not having a callback may be a valid scenario.
That's why I added a checker method, and made it available for users. I think it may be useful in a program.
The price is low. It's an inline function. It 'll just resolve to the cheap C construct  (poiner != null). 

Why assertions?

There is a hierarchy in the hurt caused by a bug:

  1. found at compilation: very low price. The developer can fix it
  2. found at test: mid cost. Developer or tester can find it. Fixed before the gizmo hits the market
  3. found in production: shame

Asserts fit in category 2. They add code to your project in the debug configuration. When you test the firmware, it can do additional (sometimes expensive) validations. And show where something invalid happens. As long as you test your code (you test it, don't you?) it 'll find logical errors that can't be found during compilation.

The release build of your project will not include these checks. So they don't add to the firmware resource reqs. It doesn't make sense to add them to the release version, because your code doesn't know to handle them anyways. That's why you want to catch them at test.

comments welcome Slight smile

Anything else?

Yes. This second post also brings joy to early adopters. To make this early project easier to grasp, I print the GPS reply to UART every time it's read. I use the Pico SDK stdio functions. So you can route it to a picoprobe or to the Pico's  USB.

image

Enjoy. Project is attached. With uf2 firmware for drag&drop.

pico_gps_teseo_i2c_20240713_03.zip

next post:  C++ library for ST Teseo GPS - pt. 3: Pico and UART support 

visit the github repository (git clone https://github.com/jancumps/pico_gps_teseo.git)
view the online documentation
Link to all posts.

  • Sign in to reply

Top Comments

  • michaelkellett
    michaelkellett 11 months ago +2
    Here's a thought, mainly applicable to high reliability hard real time systems, I like the ideas, which were very prevalent in an aerospace project on which I worked: 1) if it executes ever it executes…
  • Jan Cumps
    Jan Cumps 11 months ago in reply to michaelkellett +1
    > 2) what you test is what you ship yes. I think that asserts and printfs have a place before that moment. When the developer develops. Formal testing should be done on the production/release binaries…
Parents
  • Jan Cumps
    Jan Cumps 11 months ago

    I've added DoxyGen comments. A typical html doc page looks like this:

    image

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps 11 months ago in reply to Jan Cumps

    I managed to create an action on github, that will build and publish the docs at each commit to the main branch.

    It took a bit of effort to get this working. Here's the result:

    jancumps.github.io/.../

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • Jan Cumps
    Jan Cumps 11 months ago in reply to Jan Cumps

    I managed to create an action on github, that will build and publish the docs at each commit to the main branch.

    It took a bit of effort to get this working. Here's the result:

    jancumps.github.io/.../

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • Jan Cumps
    Jan Cumps 11 months ago in reply to Jan Cumps

    ... and the post where I explain how this is done:  GitHub: automate project documentation with DoxyGen, and publish online after pushing commits 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps 11 months ago in reply to Jan Cumps

    now moved to  GitHub: automate project documentation with DoxyGen, and publish online after pushing commits

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps 11 months ago in reply to Jan Cumps

    because the project now supports UART and I2C, I renamed the repo from pico_gps_teseo_i2c to pico_gps_teseo.
    If only I would think ahead Slight smile.

    New doco link: https://jancumps.github.io/pico_gps_teseo/

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube