Closed X-Ryl669 closed 5 years ago
I've read the code and it seems that the app needs to be flashed at 0x8001400, and it worked... once ?
Did it boot to the application once? Hmmm... What happens if you start the DPS and halt it using OpenOCD? What is the value of PC?
Got some progress. Via gdb, I see that it's crashing in ili9163c_fill_screen
in the for loop (it resets and since it's one of the first function that's called to erase the screen... I got a boot loop).
I've tried to reduce the size of the window (via gdb, I set the i
variable to 3000 to let it exit the loop, and I got a screen displaying something but it crashed later on).
When the screen is displayed, I do see the wifi icon that's blinking. The main issue I have is I'm not sure if openocd program
write more than the .text
section to flash.
I think if I succeed debugging openocd I might get progress, but openocd is behaving weirdly for me.
When I issue this:
flash info 0
device id = 0x10016420
flash size = 64kbytes
#0 : stm32f1x at 0x08000000, size 0x00010000, buswidth 0, chipwidth 0
# 0: 0x00000000 (0x1000 4kB) not protected
# 1: 0x00001000 (0x1000 4kB) not protected
# 2: 0x00002000 (0x1000 4kB) not protected
# 3: 0x00003000 (0x1000 4kB) not protected
# 4: 0x00004000 (0x1000 4kB) not protected
# 5: 0x00005000 (0x1000 4kB) not protected
# 6: 0x00006000 (0x1000 4kB) not protected
# 7: 0x00007000 (0x1000 4kB) not protected
# 8: 0x00008000 (0x1000 4kB) not protected
# 9: 0x00009000 (0x1000 4kB) not protected
# 10: 0x0000a000 (0x1000 4kB) not protected
# 11: 0x0000b000 (0x1000 4kB) not protected
# 12: 0x0000c000 (0x1000 4kB) not protected
# 13: 0x0000d000 (0x1000 4kB) not protected
# 14: 0x0000e000 (0x1000 4kB) not protected
# 15: 0x0000f000 (0x1000 4kB) not protected
STM32F100 (Low/Medium Density) - Rev: Z
I would have expected to find 64 pages of 1024 bytes (that's what ST-LINK is showing on Windows). Here it's reporting 16 pages of 4096 bytes. Obviously, it's failing to program the main program at address 0x8001400, since only 0x8001000
and 0x8002000
are possible at this granularity.
That is indeed strange. The device ID matches mine and the STM32F100 has, as you say, 64 1kb pages. Could you try to alter the start address of the app (stm32f100_app.ld) to 0x08002000 (remember to change this address in stm32f100_boot.ld too) to see if that helps. You should probably remove all flash access in past.c.
No, it does not change anything finally. I even tried to install the same openocd version as yours and it does not work either (even using your openocd/scripts).
If I skip the spi_dma_trancieve
it goes further in the boot and "blink" due to reboot loop, but at least it display the main screen each time.
void ili9163c_fill_screen(uint16_t color)
{
uint32_t i;
uint8_t hi = color >> 8;
uint8_t lo = color & 0xff;
uint8_t fill[] = {hi, lo, hi, lo, hi, lo, hi, lo, hi, lo, hi, lo, hi, lo, hi, lo};
uint8_t dummy[sizeof(fill)];
gpio_clear(TFT_A0_PORT, TFT_A0_PIN);
// ili9163c_set_window(0, 0, _GRAMWIDTH+2, _GRAMHEIGH); // Note! For some reason filling WxH is results in two vertical lines to the far right...
ili9163c_set_window(0, 0, _GRAMWIDTH, 128);//_GRAMHEIGH);
gpio_set(TFT_A0_PORT, TFT_A0_PIN);
// for (i = 0;i < 128*128/*(_GRAMWIDTH * _GRAMHEIGH)*//(sizeof(fill)/2); i++) {
// (void) spi_dma_transceive((uint8_t*) fill, sizeof(fill), (uint8_t*) dummy, sizeof(dummy));
// }
}
BTW, I don't have a "red" nor "black" PCB (tried both options, none work) but a green one for the screen PCB.
Ok, I've made some progress here:
dbg_printf("i: %u\n", i)
after the for loop, and the message goes through. Yet, it's never going further.[...]
76: f7ff fffe bl 0 <spi_dma_transceive>
7a: 3c01 subs r4, #1
7c: d1f6 bne.n 6c <ili9163c_fill_screen+0x6c>
7e: f640 2128 movw r1, #2600 ; 0xa28
82: 4803 ldr r0, [pc, #12] ; (10 <dbg_printf+0x10>)
84: f7ff fffe bl 0 <dbg_printf>
88: b008 add sp, #32
8a: bd10 pop {r4, pc}
8c: 40010c00 .word 0x40010c00
90: 00000000 .word 0x00000000
For address 8a
, we see that it's setting the PC register (and r4) to what was on the stack at this call time.
I've singlestepped until the debugger was at this point and I had the address of main() / delay_ms()
function in the stack here, instead of the address of what's after tft_clear()
.
So, what I observed was a loop across function boundaries (typically, the fill_screen function does not return, but restore the stack and fiddle with the PC register directly, and instead of storing the return address (that is, after the tft_clear()
line), it stores the address before it.
For me, it's either the compiler that's behaving clunkly (and wrong), or a stack corruption that has corrupted the return address.
Can you state what is your compiler version ? I have arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 7.2.1 20170904 (release) [ARM/embedded-7-branch revision 255204]
I've digging further to check if the stack was corrupted (by looking at what it is when entering the function).
My mistake. The stack is not currupted, it's just that fill_screen
is also called in tft_init
so having delay_ms
as return point is actually correct. It's the latter fill_screen
in tft_clear
that does not return.
I'm a bit struck here. Is there a watchdog on this system ?
Ok, I've spent a lot of time on this and finally found the solution. I've added this function in the bootloader:
#define RCC_CSR_RESET_FLAGS (RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\
RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\
RCC_CSR_PINRSTF)
const char * get_system_reset_cause(void)
{
const char * reset_cause = "TBD";
uint32_t rccFlag = RCC_CSR & RCC_CSR_RESET_FLAGS;
if (rccFlag & RCC_CSR_LPWRRSTF)
{
reset_cause = "LOW_POWER_RESET";
}
else if (rccFlag & RCC_CSR_WWDGRSTF)
{
reset_cause = "WINDOW_WATCHDOG_RESET";
}
else if (rccFlag & RCC_CSR_IWDGRSTF)
{
reset_cause = "INDEPENDENT_WATCHDOG_RESET";
}
else if (rccFlag & RCC_CSR_SFTRSTF)
{
reset_cause = "SOFTWARE_RESET"; // This reset is induced by calling the ARM CMSIS `NVIC_SystemReset()` function!
}
else if (rccFlag & RCC_CSR_PORRSTF)
{
reset_cause = "POWER-ON_RESET (POR) / POWER-DOWN_RESET (PDR)";
}
else if (rccFlag & RCC_CSR_PINRSTF)
{
reset_cause = "EXTERNAL_RESET_PIN_RESET";
}
// Clear all the reset flags or else they will remain set during future resets until system power is fully removed.
RCC_CSR ^= rccFlag;
return reset_cause;
}
And figured out that the reset was caused by INDEPENDENT_WATCHDOG_RESET
.
I've checked your code and found out there was no place where you were dealing with this IWDG.
Then, I was thinking about why nobody had the same issue as I had, and remembered the flash protection issue, where each bank was protected. So I double checked the flash's options byte.
And bingo, here's what I had:
The WDG_SW bit help is "Unchecked: HW independant watchdog, Checked: Software watchdog", so once checked the IWDG wasn't enabled by hardware upon reset and the system worked!
It seems like the manufacturer enabled those bits in addition to the flash protection for my system.
Maybe it's worth summing up all the change that I had to do to get this to work:
Target / Options byte
page of the tool.bin
file via this command:
arm-none-eabi-objcopy -O binary -S dpsboot.elf dpsboot.bin
dpsboot.bin
at address 0x8000000 and opendps.bin
at address 0x8001400 (please select the bin file first because when you do, the address is reset to 0x8000000, then change the address)Hope it helped!
Glad you sorted it out and thanks for the detailed writeup, it will help anyone unlocking using ST-LINK to unlock. On a side note the IWDG should be used to make sure we never miss an OCP interrupt.
I've a DPS3005, macOS, and did the following:
Everything in the upgrade guide (except using latest OpenOCD vs 2016 version you refered to).
Modified the opendps/opendps/Makefile model line to read:
MODEL := DPS3005
Built everything without issue (I have ARM GCC toolchain based on 7.2.1 from 20170904.
Tried to launch openocd but it failed because the script where outdated with last version
I've run openocd from
/usr/local/gnu-mcu-eclipse/openocd/0.10.0-12-20190422-2015/scripts
like this:$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg
Got this output:
Saved the 5V on/off, 3.3V on/off file (worked great), I'm not pasting them here because they are huge, let me know if you need them
Tried to unlock the flash, but this failed:
shutdown command invoked
So, this let me think about the issues I've found: