Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement button #4

Open
biemster opened this issue Sep 6, 2022 · 31 comments
Open

Implement button #4

biemster opened this issue Sep 6, 2022 · 31 comments
Labels
enhancement New feature or request

Comments

@biemster
Copy link
Owner

biemster commented Sep 6, 2022

The tags in which the chip is found usually have a button as well, it would be useful to be able to use that for example turning the tag on and off, like the original iTag firmware

@biemster biemster added the enhancement New feature or request label Sep 6, 2022
@natschil
Copy link

I tried to register a GPIO pin (in this case P18, which I know works for output) to send interrupts on click, unfortunately I was not successful here. Have you managed to trigger any kind of interrupts from button clicks?

@biemster
Copy link
Owner Author

I did not get to this yet, my time is a bit limited at the moment. I was planning to do this after getting your amazing Zigbee work implemented, so I can trigger a 802.15.4 packet by pressing a button.
Plan of attack would be to start with 17h66_blinky, and figure out which entry in the jump table gets called after button press. (I think that's easier than finding the right entry in the ISR vector, since the OSA is doing stuff there that I don't understand)
This might be a different from your use case though, because I might be just triggering the wakeup interrupt and not a GPIO interrupt..

@natschil
Copy link

natschil commented Mar 15, 2023

I was able to catch the interrupts from the button press now, it's P15 and the important thing is to pull the button gpio down since it's connecting to the positive input on the other side.

I couldn't get it to work before I'm running against the 16K memory limit of the FLASH section of the hex. I tried to increase it, but then my program fails in mysterious ways (as was the case with this GPIO issue). I'm not sure what I need to change, if I move the start I get hard faults at random places, and if I change the size my program sometimes fails to boot if I make minor changes, which to me suggests something is being overwritten.

That said, I have a device based on the ST17H66 now that connects to zigbee2mqtt and I can use to turn on/off a light which I've connected to a LED driver at the GPIO output. It took quite a while to reverse-engineer the relevant parts of the zigbee protocol, I intend to clean up+share it sometime in the near future but if anyone wants to use it before they should let me know.

@natschil
Copy link

@biemster if you have any insight into what could be done to increase the size of the flash section let me know. Most interesting to me would be to move the UART stuff onto a different SRAM since UART should be disabled to conserve power anyways.

@natschil
Copy link

Speaking of power conservation - thanks to the amazing work of @biemster and others, the zigbee light controller mentioned earlier consumes only around 80 micro-amps of power when idle (it polls for messages at a 3s interval).

@biemster
Copy link
Owner Author

That is awesome work @natschil! This would probably also open up the possibility to use the st17h66 as a zigbee sniffer when connecting a PC to the uart?
On the increase of flash section, is it possible that the SRAM retention is only on SRAM0, so the rest gets lost when the chip goes to sleep?
I haven't messed around with the linker script recently, but that's likely where the changes should go. Did you try compiling with Keil as well, to see if you can use more than 16k that way? That's how I would go about it, first get it to work with uVision, then GCC.

@biemster
Copy link
Owner Author

Also, now I think of it, there is a XIP section that GCC is not using in the linker script. Maybe that's worth investigating?

@natschil
Copy link

Yes, using the st17h66 as a zigbee sniffer should be relatively straightforward, there are two issues though:
a) bandwidth, you'll have to make sure to forward the zigbee messages quickly enough, you may or may not miss some messages if it doesn't listen while processing.

b) getting them into a format wireshark understands (pcap)

@natschil
Copy link

that's an interesting point regarding SRAM0, I will definitely need to look into that.

@natschil
Copy link

I really dislike having to boot windows, so if I can avoid it usually I do :D but maybe I will have to try Keil...

@biemster
Copy link
Owner Author

that's an interesting point regarding SRAM0, I will definitely need to look into that.

// hal_pwrmgr_RAM_retention(RET_SRAM0|RET_SRAM1|RET_SRAM2);

@biemster
Copy link
Owner Author

I really dislike having to boot windows, so if I can avoid it usually I do :D but maybe I will have to try Keil...

So do I! I run it under wine actually, is that an option for you?

@natschil
Copy link

yeah running it on wine should work

@natschil
Copy link

If we compare this
image
to this
image
, the things in FLASH really shouldn't be leaking out of SRAM0. What I don't really understand is what is between the GLOBAL_CONFIG and the FLASH sections - after all, there should be 4152 free bytes there which would be nice to use.

@biemster
Copy link
Owner Author

Yeah I never understood really what is going on there, I just happened to stumble upon values that worked :). In my naive interpretation, FLASH is spilling over in RAM here. The original linker script is using something different:

/* Linker script to configure memory regions. */
MEMORY
{
  /* In mirror mode, flash content is copied to RAM and progrm execute in RAM */
  FLASH (rx)  : ORIGIN = 0x1FFF4000, LENGTH = 64K /*Mirror mode : flash is copied to RAM for execution*/
  RAM   (rwx) : ORIGIN = 0x20004000, LENGTH = 48K

  JUMP_TABLE (rwx)       : ORIGIN = 0x1FFF0800, LENGTH = 1K
  GLOBAL_CONFIG (rwx)    : ORIGIN = 0x1FFF0C00, LENGTH = 1K 
}

But I have no clue what mirror mode is, and why the jump table is in the wrong place.
The values I came up with are mostly from the uVision linker info, with some guesswork added to it.

@natschil
Copy link

oh yeah you're right, flash is spilling over to ram here.

@natschil
Copy link

Ok, so according to misc/bb_rom_sym_m0.txt, there are a bunch of addresses there that would go in the region between GLOBAL_CONFIG and RAM, not sure what to make of it:

image

@biemster
Copy link
Owner Author

Those are actually between the end of GLOBAL_CONFIG and the beginning of FLASH in the current linker script right? That's a nice find actually, that explains why the SDK code starts at the weird address of 0x1FFF1838. Maybe some patch / revision of the rtos is put there in the factory?

@natschil
Copy link

I tried to move all the UART stuff into SRAM1, but as far as I can tell this doesn't play well with the current flasher script - while I don't get any errors, the chip doesn't boot into anything that does anything as far as I can tell. Anyways, giving up for now, might try again on the weekend or so.

@natschil
Copy link

To be fair, I don't really understand what is going on here. After all, the flashing shouldn't directly write to SRAM{0,1,2}, but these sections are loaded from flash memory I guess on boot? At least otherwise I don't see how the program being flashed would persist accross power loss...

@natschil
Copy link

natschil commented Mar 15, 2023

I thought about this a bit more, and I think I understand the flasher a bit more now (this might be completely obvious to you already):

image
Here, the cpbin .... command copies the hex file to flash memory (which starts at 0x1100 0000 according to the datasheet)

This is however where I start to get confused, the flash memory according to the datasheet is processed the following way:
image

But as far as I can tell, the flasher doesn't even write anything to the first 0x2000 = 8192 bytes of flash. It just copies c0 at 0x2000 in flash, which looks like this:
image

Now if I'd have to guess, I'd say that "00500000FFFF00000000FF1FFFFFFFFF" copies fromflash address 0x5000 to SRAM (0x1fff0000) - the number of bytes is specified in the python program below and corresponds to the jump table

The next line "{SZ}0000FFFF00003818FF1FFFFFFFFF", then copies the actual program, here {SZ} is presumably some compiler-specific header size or something.

@biemster
Copy link
Owner Author

c0 is the ihex header, it's not even in the output of the compiler. I never really payed much attention to this further after getting it to work, but if you want to know exactly what is in here I guess the ihex spec is the place to look?

@natschil
Copy link

Here's an interesting image taken from the Lenze documentation, though it pertains to the OTA update it might nevertheless have some relevance.
image

@biemster
Copy link
Owner Author

Nice find! I don't remember seeing this table before, is it in the ST17h66 datasheet?

@natschil
Copy link

It's in the ST17H66 EVB 开发用户手册.pdf file at https://doc.lenze.club/?filePath=%2Fpublic%2Fstore%2F17H6X%28Flash%29 (unfortunately I don't remember which directory exactly it was in, as firefox seems to forget this)

@natschil
Copy link

I was looking at the st17h66_blinky example, and it seems to have a slightly different flashing script - in particular the main program isn't at 0x11005000 but at 0x11009000. Any reason for this? Very bizarrely, I'm able to move this address there to any address between 0x11005000 and (roughtly) 0x11040000 , but making this change on my larger example fails...

@natschil
Copy link

I really don't understand what {SZ} is doing there, do you have any insight into what this variable is?

@biemster
Copy link
Owner Author

The 0x11005000 or 0x11009000 I took from the LeKit software, I first flash it with this and then mimic the behavior in the python flasher. Not sure why LeKit chooses one or the other, but I did notice that the amount of hex segments (c{0,1,2,..}) influences this.
Same for the {SZ} variable, I noticed that LeKit is using different values for this sometimes. Did not investigate yet what those mean.

@natschil
Copy link

Somehow I got writing to XIP to work. I'm still quite surprised - at one point I gave up from frustration, did a git reset --hard on all my changes and then tried again, and it worked. Basically there isn't anything to it, except that the objcopy part of the makefile now looks like this:

$(BUILD)/$(BIN).hex: $(BUILD)/$(BIN).elf
        @echo OBJCOPY $@
        @$(OBJCOPY) -O ihex --only-section .jump_table_mem_area --only-section .global_config_area $^ build/headers.hex
        @$(OBJCOPY) -O ihex --remove-section .jump_table_mem_area --remove-section .global_config_area --remove-section .xip $^ build/sram0.hex
        @$(OBJCOPY) -O ihex --only-section .xip $^ build/xip.hex
        cat build/headers.hex build/sram0.hex build/xip.hex > $@

and I took the c1,c2,c3 version of your excellent flasher from biemster/FindMy#5

@natschil
Copy link

Oh yeah and the linker script needs some minor changes too
image
image
Basically I'm manually setting functions I want in xip with __attribute__((section(".xip")) because I'm not entirely sure what (if any) power management implications running from XIP has

@biemster
Copy link
Owner Author

Awesome! great work here. I was under the impression that running from XIP is more efficient (read it somewhere), but the code has to be compatible. I did not really look into this yet, but I sure will now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants