biemster / st17h66_blinky

Minimal code to blink the LED on Lenze st17h66 based tags
6 stars 1 forks source link

Compilation instructions #4

Open natschil opened 1 year ago

natschil commented 1 year ago

I just came across this project looking for a way to program a ST17H66. I'm very impressed, this looks exactly like the kind of thing I was looking for.

That said: I'm wondering what I need to compile this. What I did now was to download https://github.com/ARM-software/CMSIS and then add the headers from there to the include directories. It seems to compile fine, but I'm wondering if I'm doing the right thing or not :)

Edit: I'm using gcc on linux in case this is relevant.

biemster commented 1 year ago

Nice! This is actually one repo in a series, but you might have figured that out already: https://github.com/biemster/st17h66_RF https://github.com/biemster/st17h66_FindMy

with the FindMy stuff being the final goal (that one also has a very interesting discussion (biemster/st17h66_FindMy#7) on power consumption). I've just managed to compile with GCC (was quite a journey, took me more than a year I think), and the st17h66_RF is actually the best example if you really need GCC (that's as hot as it gets, I just managed that yesterday!). The other two (and also RF) compile with Keil uVision as the original SDK intended.

Long story short, to compile in GCC you need to checkout CMSIS as described in the st17h66_FindMy README.md, that's all. The Makefile should find it then, no extra includes needed. So this is still very much active development, and flashing is also not really straightforward yet, so feel free to ask any questions you might have along the way. And definitely keep me posted on what you build with this chip, since I think that if you start writing code you and me are the complete open source dev team for this globally!

biemster commented 1 year ago

So yeah, since compiling on GCC is still so recent I did not get to writing how to do that in the readme. That will happen somewhere this week. Also, support for compiling with Keil uVision will very likely be deprecated and removed since it is quite cumbersome for me to maintain (no Windows household).

natschil commented 1 year ago

Thanks! That sounds very promising. I will try to compile once I've successfully flashed anything. I've connected P09 and P10 to a USB serial and GND/V3.3 to an external power source. However, I'm not getting back "cmd<<".

The chip is actually marked ST17H66B, and is part of an "iTag" like this one: https://content.instructables.com/FI4/9RDE/KVP8ZV3J/FI49RDEKVP8ZV3J.png?auto=webp&frame=1&width=931&fit=bounds&md=f2cf545d739aa95e248e5efabc043cc1 . What's nice is that there are debug points accessible on the back (P9,P10, SWS, P18, GND, 3.3V+).

Pressing the button (which is connected to P15, I'm trying to follow https://github.com/vadimkozhin/st17h66-OHS-tag/tree/main/flash_tool) while flashing with the python flasher gives me back all kinds of junk over serial. Normally this button is used to start/shutdown the device, when it emits a double/single beep respectively. This is what happens when connected over serial too, except for that the beeps are associated with junk being written to serial.

natschil commented 1 year ago

Ah was a stupid mistake on my side, I didn't connect the GND of the usb to UART

natschil commented 1 year ago

And I was succesfully able to compile and flash the blinking example :tada:

Thanks again for the great work!

natschil commented 1 year ago

What does https://github.com/biemster/st17h66_RF actually do? My end goal at the moment is to make a small bluetooth receiver attached to a mosfet, so if I can use it to receive some packets that would be very very cool.

biemster commented 1 year ago

Yes I don't think pressing the button is necessary, I never do that. And all soc's I have and have seen are ST17H66B indeed. st17h66_RF at the moment only sends out an advertisement, without initializing the BLE stack. It also listens for advertisements sent by other devices, but that code is commented out for now (since I am trying to make a FindMy tag out of it)

biemster commented 1 year ago

Also to note, sleep is not working yet on blinky, but does work on the _RF repo. So if you want to build a receiver that sleeps most of the time, the _RF repo is what you should focus on. (and on top of that, there is no RF at all in blinky, so another reason to use _RF as your base :) )

biemster commented 1 year ago

What instructable is that photo you linked part of?

natschil commented 1 year ago

It's from this page https://www.instructables.com/HackerBox-0072-Tagger/ , which google images gave me when searching for the chip

natschil commented 1 year ago

The st17h66_RF branch is working nicely. It's a bit of a cumbersome to manually construct BLE advertisement packets, but I think I have it working more or less. Which (commented out) code listens to advertisements?

biemster commented 1 year ago

In https://github.com/biemster/st17h66_RF/blob/main/source/Lenze_phy.c#L545 I commented out the start of the RX timer, just uncomment that line and it should start listening again.

I just remembered that I also turned off UART, to save power, but that will make debugging a bit more difficult ofcourse.. There is not a really easy way to turn that back on again I'm afraid, I took out quite a bit of code for that. But you probably can find that in the git history of that repo. https://github.com/biemster/st17h66_RF/commit/aadafcb1259992e3a022407818f5cf4dfa369651

natschil commented 1 year ago

Thanks! UART would be a big help here. I'm very familiar with C, but don't have so much experience with compilation for the embedded context. Where do the symbols in include/rom_sym_def.h come from? Adding uart.c gives me the error " #define disableSleep _symrom_disableSleep" and my suspicion is that I somehow need to update those symbols.

natschil commented 1 year ago

nevermind, I think I got it. What is the advantage of manually only selecting a small subset of the used symbols?

natschil commented 1 year ago

It seems that including uart doesn't work on gcc though, there I get '/usr/lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld: build/Lenze_RF.elf section .text' will not fit in regionFLASH' /usr/lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 968 bytes'

natschil commented 1 year ago

It seems like increasing the size of the FLASH region works

natschil commented 1 year ago

That said I'm still not able to view any log output, calling LOG_INIT() in main.c() results in lots of output to UART (I hear noise on buzzer) despite not actually sending anything. Maybe there is some interference from the firmware going into sleep mode?

natschil commented 1 year ago

Hmm seems like I may have no adjusted the size of the FLASH region correctly. Once the program gets larger than 4k, it seems like various functionalities don't work anymore. Here is how I adjusted the size of the FLASH region:

/ Linker script to configure memory regions. / MEMORY { JUMP_TABLE (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x400 GLOBAL_CONFIG (rwx) : ORIGIN = 0x1FFF0400, LENGTH = 0x400 FLASH (rx) : ORIGIN = 0x1FFF1838, LENGTH = 0x5000 RAM (rwx) : ORIGIN = 0x1FFF6000, LENGTH = 0x1000 }

natschil commented 1 year ago

Compiling with "-Oz" allows me to access UART. The 4k binary size seems to be a GCC limitation with the current setup.

biemster commented 1 year ago

nevermind, I think I got it. What is the advantage of manually only selecting a small subset of the used symbols?

There is no benefit, I'm still trying to understand all the code and having the absolute minimum is helping me get there. great you figured it out!

biemster commented 1 year ago

Where do the symbols in include/rom_sym_def.h come from?

Thats all from bb_rom_sym_mo.txt, as far as I understand that's hardcoded stuff from the ROM the chip ships with.

biemster commented 1 year ago

Once the program gets larger than 4k, it seems like various functionalities don't work anymore. Here is how I adjusted the size of the FLASH region:

I've been playing a lot with that as well, all trial and error. Motivated by the info from the SDK that SRAM0 is between 0x1FFF000 and 0x1FFF8000, which is kept warm during sleep, I tried to fit everything in there. The chip has more RAM, which requires some extra power consumption during sleep to keep alive.

biemster commented 1 year ago

Compiling with "-Oz" allows me to access UART. The 4k binary size seems to be a GCC limitation with the current setup.

Maybe adding SRAM1 and SRAM2 here: https://github.com/biemster/st17h66_RF/blob/main/main.c#L120 will extend the size limit another 4k? Or preventing sleep altogether should be an option too if you are running from something bigger than a coin cell. EDIT: also, what is "-Oz"? Can't find that in the manual.. "-Os" is optimize for size right?

biemster commented 1 year ago

If you are still searching to get the firmware smaller, disabling SPI flash cache here: https://github.com/biemster/st17h66_RF/blob/main/main.c#L162 makes the resulting binary almost 10% smaller

natschil commented 1 year ago

"-Oz" is " Optimize aggressively for size rather than speed", see here: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

natschil commented 1 year ago

Since the code parts are read-only, I'm not sure why it would need to be placed in the rw memory that is kept alive during sleep, e.g. I wonder how much of the 256k NOR memory mentioned here is usable: https://www.lenzetech.com/public/store/pdf/jsggs/ST17H66B2_BLE_SoC_Datasheet_v1.1.2.

I cannot imagine that a simple UART stack and some bluetooth send/receive commands would fill the memory of this chip...

Edit: just saw that page 5 of the link above shows the entire memory layout, will experiment with that a bit tomorrow.

Edit2: SRAM0 is apparently 32k, there has to be some way of using more of that...

biemster commented 1 year ago

Edit2: SRAM0 is apparently 32k, there has to be some way of using more of that...

I actually wrote this off as confusing bits and bytes, in my head 4kB is 32kbits and I just moved on without investigating.. Maybe I should have a look at this again.

natschil commented 1 year ago

Between 0x1FFF_0000 and 0x1FFF_8000 there are 0x4000=32k bytes. Between GLOBAL_CONFIG (ends at 0x1FFF0800) and RAM (starts at 0x1FFF6000) there should be 0x5800 bytes free. However, if I start FLASH =0x1FFF0800 nothing runs. Is there anywhere else I need to specify the start of the FLASH section?

biemster commented 1 year ago

Yeah the flasher script has a hardcoded address for this in the hexf header (3818): https://github.com/biemster/st17h66_blinky/blob/main/flash_st17h66.py#L31 and https://github.com/biemster/st17h66_blinky/blob/main/flash_st17h66.py#L47

You could use the LeKit flasher from the SDK to get around this, or even try (I did not try this yet): https://github.com/diskman88/PHY6212/blob/master/applications/seneasy/SRC-PHY6212-EVB/tools/phytool.py the LeKit can also create only the hexf, from which you can then extract the header if you prefer the python flasher.

the flashers included in my repos are quite prone to breaking when working on the memory layouts.

EDIT: I kept it on 0x3818 so the flasher could flash both the Keil generated binary and the GCC generated one.

natschil commented 1 year ago

ah interesting. Are you also hard-coding the end of the FLASH region in the flasher? I would prefer not to use windows since I have to reboot my machine to access it, so maybe there is a way to do it like this after all.

biemster commented 1 year ago

The hexf header has the pointer to the __initial_sp, and the sizes of the sections it uses. The cpbin command contains some address in flash where it should be burned and a length, and also some second address which seems to be ignored. But I am not very knowledgeable in this deep stuff, so most of what I'm doing is trial and error.

LeKit runs fine in wine, that's what I'm using. But I also highly prefer the python flasher, I'm going to give that phytool.py a try soon (although it seems it requires some minor changes)