2024-12-31 11:15 AM - edited 2024-12-31 11:16 AM
STM32F407G DISC-1 STMCubeIDE
Greetings, I am trying to send data to LCD screen by using I2C Communication Protocol. I succeed in doing it by using HAL library. Also, my current work does work in debug mode.However, I could not make it work by running it normally.
I did it in HAL by using the same clock, frequency configurations. I could not find the problem.
Here is my code:
int main(void)
{
GPIO_Handle_t I2C1_SCL_PB6 = { .PORTNAME = GPIOB,
.PINCONF.PIN = GPIO_PIN_6,
.PINCONF.MODE = GPIO_MODE_ALTARNATE,
.PINCONF.OTYPE = GPIO_OTYPE_OD,
.PINCONF.OSPEED = GPIO_OSPEED_VHIGH,
.PINCONF.PUPD = GPIO_PUPD_PU,
.PINCONF.AF = AF4
};
GPIO_Handle_t I2C1_SDA_PB7 = { .PORTNAME = GPIOB,
.PINCONF.PIN = GPIO_PIN_7,
.PINCONF.MODE = GPIO_MODE_ALTARNATE,
.PINCONF.OTYPE = GPIO_OTYPE_OD,
.PINCONF.OSPEED = GPIO_OSPEED_VHIGH,
.PINCONF.PUPD = GPIO_PUPD_PU,
.PINCONF.AF = AF4
};
gpioInit(&I2C1_SCL_PB6);
gpioInit(&I2C1_SDA_PB7);
I2C1_CLOCK_ENABLE();
I2C1_FREQ_16MHZ();
I2C1_FREQ_SCL_100MHZ();
I2C1_RISE_TIME_17();
I2C1_ENABLE();
I2C1_ACK_ENABLE();
I2C1_START_GENERATION();
I2C1->I2C_DR = SLAVE_ADDRESS_LCD;
lcd_init ();
lcd_send_string ("ABCDE");
while(1)
{
}
}
2024-12-31 11:42 AM
It is hard to tell why "normal" mode does not work (you mean booting itself from flash, w/o debugger loading the code).
Do you any clock configuration without debugger? You code in main() just uses I2C config, nothing else. But booting from flash my need a lot more initialization code (e.g. clock config, flash latency, ...).
Also possible that you build with Linker Script a code image which is loaded and running from SRAM. The debugger will load fine and launch the code on SRAM. But in "normal" mode - there is no SRAM content.
Do you have any simple FW example, e.g. toggling an LED, which runs in "normal" mode? Check what all is done in main() and how your Linker Script will build and load the image. Extend such a "normal" project with your code.
My guess: you build FW to load and run only in SRAM (not properly booting from flash).
2024-12-31 12:02 PM
@tjaekel Yes, basically importing the code into the MCU by clicking RUN icon. I have no clock config it uses default HSI 16Mhz.
Sorry, I could not understand fully your point but I am able to toggle some LEDs with the same structure as the above code.
2024-12-31 04:47 PM
Let it "run normally" then when it isn't doing what you want, launch a debugger configuration without downloading new code or resetting the chip and find out where it is and why it's there.
Could also use a logic analyzer to watch the I2C lines.
2024-12-31 05:23 PM
I mean: if your project is setup and built (with Linker Script) to be loaded and run in SRAM - with debugger is works fine. But it cannot boot with code "this" stored in flash ROM.
What is your Linker Script?
Yes: try to boot from flash ("normal"), have debugger connected and try to stop debugger, step with debugger... which code is executed? Where are you in code execution?
I assume (still): you create a code image which works fine when debugger loads code to SRAM - but it cannot run the code from flash ROM (as "normal", potentially no code in flash ROM).
Use the debugger in order to check:
I think: if code works with debugger loading and launching the code (on SRAM) - but as "normal" (booting the code stored in flash) it does not work:
Just boot in "normal" mode, connect with debugger (the running session) - check what is in flash memory, what is on SRAM, where is the Program Counter (PC, which code does it try to execute)...
Or:
Set a breakpoint in debugger mode on the very instruction done (not on main(), instead a breakpoint on first instruction in ResetHandler.
Set compile options to "-g" and "optimize for debug".
Try to figure out if SRAM is initialized (startup.S was working), if code was written into flash ROM... how the code jumps (in "normal" mode), if startup.S has initialized SRAM...
For me it sounds more as: you build code to be loaded into SRAM via debugger (therefore it works), but without debugger ("normal") there is code in flash ROM.
You can try to flash the code generated also via STM32Programmer: flash the ROM with the BIN file.
But if the linker script has all bound to SRAM addresses it can still fail.
Just post the content of your Linker Script you use.
And tell us what is flashed in Flash Memory. What is the SRAM content before and after "startup.S" was executed?
The debugger is your best friend.
2025-01-01 05:42 AM
I checked my project uses either FLASH or RAM by looking here.
In my STM32F407VGTX_FLASH.ld file. It seems OK.
/* Memories definition */
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
and I realized somehing I have tried running it several times later on and was receiving this message
This must be the problem causing everything goes bad. What should I do at this point. I am quite confused.
Thanks for your attention
2025-01-01 11:58 AM
OK, this looks reasonable (Linker Script for booting from flash).
This message about source code not found is potentially due to missing debug option flags.
Find the "Debug level" settings and "Optimization" (set for debug). For ResetHandler, which is in assembly file "startup.S" - you have to select also -g3 in the Assembler part config.
2025-01-01 12:32 PM - edited 2025-01-01 12:32 PM
"Debug level" in the above had been already set as "-g3" and also optimization level was (none-O0). @tjaekel
2025-01-01 01:16 PM
Set optimization to "Optimize for debug (-Og)".
You should be able to see the Reset_Handler code (the assembly code).
There is a way to show the "Disassembly" and to step trough on single assembler instructions.
Find the Reset_Handler entry address in flash ROM: it should be the second 32bit in vector table (memory dump at 0x08000000). The second word is address where Reset_Handler starts (the first the top address of SP).
Use Disassembly view and single assembler instruction steps.
If you do not see any Reset_Handler - it would look strange to me. Maybe you do not have a startup.S file?
Does it jump immediately to main()? There must be a startup sequence which copies code and data from flash ROM into RAM.
In the debugger configuration is also an option to set a breakpoint at Reset_Handler (and not just main):
Can you see the Reset_Handler code and step from there?
2025-01-01 02:47 PM
08000526: movs r0, r0
main:
08000528: push {lr}
0800052a: sub sp, #28
33 GPIO_Handle_t I2C1_SCL_PB6 = { .PORTNAME = GPIOB,
0800052c: ldr r3, [pc, #144] @ (0x80005c0 <main+152>)
0800052e: add.w r12, sp, #12
08000532: ldmia.w r3, {r0, r1, r2}
08000536: stmia.w r12, {r0, r1, r2}
42 GPIO_Handle_t I2C1_SDA_PB7 = { .PORTNAME = GPIOB,
0800053a: mov r4, sp
0800053c: adds r3, #12
This is disassemble view, it indicates line6 at the beginning.
This is memory view.
I replaced Reset_Handler with main in the debugger configuration, I can move forward step by step from here. @tjaekel