Reviving RAK811 support

Hi All,

I’m trying to revive MBed6 support for RAK811 in a custom board target.

I’m writing this post for two reasons:

  1. in the hopes that someone with more knowledge may give me some guidance in how to get the module working again
  2. hoping it may help anyone else that needs to get a STM32 chip working.

Progress to date:

Generating Mbed HAL STM32 chip specific code:

  1. I’ve discovered that the STM32 custom targets repo (@jeromecoutant mentioned to me in another thread) doesn’t have support for the RAK811, or the STM32L151CB chip it is based on.
  2. The make_generic_boards.py script fails as it can’t download the correct file from STM32 open pin data repo
  3. That repo is a subset of files that have been open sourced from STCubeMX, so I found the correct file in my local installation (This could mean licensing is an issue preventing me from sharing the remainder of my work - or even using the file? I haven’t yet found a licensing statement anywhere clearly covering the specific files, so I’ll have to re-read the EULA I guess, and that seems likely to reserve all rights just to be safe. I guess it’s only copyright, so I can manually recreate the file without infringing that if this process works…)
  4. I’ve symlinked the correct dir from the STMCubeMX , manually run the STM32_gen_PeripheralPins.py script with -n, modified the make_generic_boards.py script to skip calling the STM32_PeripheralPins.py (just use the already generated directories and files), and successfully generated PinNames.h, PeripheralPins.c and an almost empty system_clock.c
  5. I’ve modified the STM32[L1] Mbed HAL code to compile: I’ve configured MST timer to use TIM4 as TIM5 isn’t available (and then discovered that TIM4 may be in use for LPTicker by the look of it, though I want it to use the RTC - work left to do to confirm config here ensure not conflicting)
  6. I’ve accounted for expected peripherals that are missing on this chip: SPI3 is now contingent on UART3_BASE being defined, ditto PWM5 and TIM 5
  7. I’ve modified RTC to only use SSR if the chip is not defined as STM32L1_CAT1 (as they are value devices without the SSR)

The code now compiles, but is not yet tested.

I haven’t yet investigated how to get TICKLESS support or how to make the LPTicker use the RTC. I suspect there could be more gotchas identified when resolving those two, or not even thought of yet.

If anyone knows what else may need addressing, suggestions would be appreciated!

@jeromecoutant I notice that you are very active in the stm32customtargets repo, so I was hoping you may be able to comment on:

  1. why the STM32L151xB boards are not part of stm32 open pin data, or if there is any hope that it could be made available?
  2. Will the licensing prevent me sharing the target if/when it’s complete? Can anything be done about that?
  3. I’ll need to make minor mods to the stm32 code in mbed to remove the dependency on inaccessible peripherals in the mbed repo. in partnership with the custom target (the generic driver code assumes TIM5, SPI3 and RTC->SSR exist, but they don’t on this chip). What’s the best way to deal with that?

I’d upload all this code to my own git repo, but I don’t want to start sharing copyright protected files.

I’ll post progress updates when they are made, but it’s a low priority hobby project for now so it may be a few days before the next update.

Thanks,

W.

Hi All,

Just a quick note to say that I’ve checked on the LP_TIM:

  • The STM32 system defaults to using the RTC, unless a config variable target.lpticker_lptim is added to mbed_app.json (I assume this could be added to a target definition file to default to use lptim, but not familiar enough with the mbed config system yet to be certain).
  • I’ve modified coded and confirmed that the code that compiles is currently using the RTC for LPTicker.

In conclusion as I now understand it: the code I have for the STM32L151xB MCU should use the RTC for LP_TIM and only use TIM4 as MST (uS timer in my book).

As I understand it, the system should work, though I want to check if anything further is required for TICKLESS support.

W.

Hi All,

Another brief update:

  • there is a requirement from mbed clocks that they tick at 8kHz or faster, and that (I think) means that the device MUST have and SSR.
  • I checked the mbed 5 code for the RAK811 module and it uses the STM32L151CBA, which makes it a category 2 device and it does have the SSR.
  • I can’t see any obvious files in the device database that map to a STM32L151CBA.
  • Looking on the website, there is a STM32L151CB-A or an STM31L151CB… I think they have the same pin map either way…

There is no MCU_STM32L151xBA or MCU_STM32L151CBA (or similar) that I can find in the mbed-os/targets/targets.json.

Using the linker script from the STM31L151xB, and blinking an LED works (written from scratch using ‘baremetal’ profile).

W.

I’ve already noticed that the open pin data does have the file for the STM32L151CBxxA in place, which I think is the correct file for this processor (though probably has the same pin map anyway).

I now intend to go back through the whole process now I have a better understanding, I’m sure there will be other corrections along the way…

Just a quick update to document an issue I’ve spotted:

I’ve been testing the RAK811 with it’s current implementation: GPIO works, SPI works and UART mainly works (not entirely unexpected given that I haven’t really coded anything!)

There is an odd phenomenon that I haven’t yet traced with UART (perhaps other peripherals due to a clock issue?)

The symptom I’ve seen is:
If I use printf("Anything\r\n") in the main method before entering a periodic event loop with another printf("periodic\r\n") output, the BAUD changes between the initial printf and the subsequent periodic output. It becomes double the intended BAUD.

If I do not print anything in main it doesn’t happen - the periodic print out transfers at the correct baud for all periodic updates.

It would be great if someone who has experience of STM32 chip support could comment!

Hi

I tried to read all and make few first answers:

I’ve discovered that the STM32 custom targets repo (@jeromecoutant mentioned to me in another thread) doesn’t have support for the RAK811, or the STM32L151CB chip it is based on.

Yes, no one has proposed this one yet!
Please push a PR there, I will be happy to review and merge!

The make_generic_boards.py script fails as it can’t download the correct file from STM32 open pin data repo

It is true that scripts in this GENERIC_TARGET branch are not supposed to be used :slight_smile:
I saved them more for information and for archive.

What I see from:

is that MCU_STM32L151xB is missing in mbed-os.
This I can try to correct this soon !

In conclusion as I now understand it: the code I have for the STM32L151xB MCU should use the RTC for LP_TIM and only use TIM4 as MST (uS timer in my book).

STM32L1 doesn’t support ST LPTIM IP.
So,

  • TIMx is used for MBED USTICKER
  • RTC is used for MBED LPTICKER

Note we never fully validated TICKLESS support for STM32 without LPTIM

Not sure…
Looking at RAK811 WisDuo LPWAN Module Datasheet | RAKwireless Documentation Center
seems STM32L151CBU6 is used not the “A” version…

Please check:

and

Hi @jeromecoutant

Thanks for the support and feedback!

I’ll give these a run and see what happens in the next day or two.

They are very similar to some of the changes I had implemented, but I hadn’t neatened up my code yet (I made too many changes, then deleted some, but haven’t yet recreated as I had intended to get a minimal set of changes and then submit a PR).

I’ve spotted one difference between our implementations so far…

I may be wrong, but I am under the impression that TIM2 is 16 bit on these devices, and I notice that you didn’t include the following line in the #if defined TIM5_BASE and #else:

49:  #define TIM_MST_BIT_WIDTH  32 // 16 or 32

In: targets/TARGET_STM/TARGET_STM32L1/us_ticker_data.h

Also I thought the RAK811 was based on the ‘CBA’ version due to targets.json from mbed-os 5.15.8

I’ll check what my hardware actually IS when I next get an opportunity (hopefully using the DEV_ID will be sufficient?)

Though thinking about it it just wont work if I use the ‘CBA’ and it is really a ‘CB’ as that’ll try to use 32KB and the stack will be totally in non-existent RAM…?

Sorry - too tired to write simple English! If you need me to make more sense than that I’ll try again another day!

The most important point is ‘Thanks for the help!’

Hi again,

I just realised I could check the linker script that I have successfully used on the RAK811: it confirms the RAM is 32KB and I believe that means it must be a CBA:

Later in the file it place the STACK at the top of RAM (as usual) so this device MUST have 32KB of RAM, or the entire stack would be at an invalid address and triggering address faults instead of doing anything useful.

I’ll check the DEV_ID when I get a chancel, but I now expect I’ll be using the GENERIC_STM32L151CBA as the basis for developing the 'RAK811_BREAKOUT ’ custom board. (The only think really left to do is to define the LoRa pins and remove unusable peripherals, as I understand it).

Good catch, this is corrected in the PR

Good idea. Looking at RM, I think you will get 0x416, you think 0x429 :slight_smile:

Not sure, it proves something… Set 0x80000, link will work as well ?

Using OpenOCD… and the answer is …

> mdb 0xE0042000 4
mdb 0xE0042000 4
0xe0042000: 29 64 38 10

bottom 11 bits: 0x429 I reckon!

(showing working because I could easily have made a mistake - e.g. I haven’t even double checked the endian-ness and I’m very forgetful on those details, or this could be the wrong address to check, so any feedback appreciated!)

I agree, the linking script alone doesn’t prove anything and could link at any address but wouldn’t run.

The fact that I’ve run code that actually runs on the device AND uses that linking script shows that the device must have had 32KB of RAM, because the stack was in the last 4KB of the RAM and the device wouldn’t do anything useful if the stack tried to use RAM that didn’t exist.

(Sorry if I’ve missed your point and just re-iterated my logic…)


Whatever the outcome of these details - thanks again for the help!

Good news for you. So schematics I found were wrong…

Now, RAK811 should inherit from “MCU_STM32L151xBA” like for:

So some bad news @jeromecoutant: your version still exhibits the unusual behaviour where the baud rate changes between ‘main’ and subsequent periodic reporting. (documented above, but it’s mixed in with other things, so may be easier to read my repo README below)

I’ve created a repository with a minimal application and based on the following, so it is as stable as possible:
mbed-os 6.15.0 + your cherry-picked PR
stm32customtargets:GENERIC_TARGETS + Your latest commit - new MCUs not supported by 6.15.0

It’s all in:
minimal_mbed_rak811_app

NB: I’m using the somewhat under-used git submodule so read the README.md if you’re not familiar.

Any idea why the BAUD would double if (and only if) there is a printf in the main method before entering the dispatch loop?

Alternatively, if you have any ideas that are worth exploring about what the trigger could be I’d appreciate all thoughts.

Thanks again!

For convenience of anyone following along in future, I’ll replicate @jeromecoutant 's important suggestion in my git repo here:

Maybe a correct SetSysClock function is missing ?

This is likely to be the answer!

I’m not familiar enough to know that I had to implement this, and I must have missed it in the docs I guess, but the device is currently executing without a functional ‘SetSysClock’ - it currently is implemented, but devoid of code:

MBED_WEAK void SetSysClock(void)
{
}

I do not have any code to override it, and can’t see any in the mbed-os/targets/TARGET_STM or stm32customtargets. I had just imagined that this was a vestigial legacy, or optional extra and the system got it’s clock configuration from the mbed configuration system (I hadn’t even looked to confirm that it was using the HSE, but know it’s configured for an LSE that way)

I will look for a similar function to what I need and learn what I can from that. Any tips on how to generate one would be appreciated.

@jeromecoutant: Thanks for the helpful suggestion!

Try to copy this one?

Hi @jeromecoutant - that worked perfectly and fixed the issue with serial baud.

It also smoothed out a corner: I had assumed there was an HSE, but it’s not there!

I’ll re-read the docs on how to generate a new board to ensure there are no more things I have forgotten to do, then put this through it’s paces.

I haven’t yet run any greentea tests on a device - partly because I’m developing on one computer and uploading images through a server, so I’ve always used openocd (or occassionally stm32cube programmer), so I’ll give greentea a go too.

I’ve just separated the code in to a RAK811 custom target, currently called ‘MTB_RAK811’ to match the original implementation. I am not familiar with the ‘MTB’ designation which I guess is an acronym, and wondering what a sensible name for this board would be now: does ‘MTB’ still apply?

@jeromecoutant Sorry to bug you again, but I’m hoping you may be able to comment: is there a better name? (may save submitting a PR just to have a bounce back to change the name).

I’ve been able to test the LoRa/LoRaWAN working with this board, so SPI and timing is working nicely in baremetal mode.

Not sure/doubt I’ve run in ‘TICKLESS’ mode - and I haven’t run any automated tests yet, but moving the right way…

Hi
I made some historical reseach :slight_smile:
I think MTB is Module Test Board…

And yes, keep this name to match mbed detect tool:

You are ready to push in GitHub - ARMmbed/stm32customtargets: Enable the support of your custom boards in mbed-os 6!