cancel
Showing results for 
Search instead for 
Did you mean: 

Using I2C Communication Protocol via LCD

Khansokhua
Associate II

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)
			{
			}

}

 

 

 

14 REPLIES 14
tjaekel
Lead

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).

@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.

 

TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".

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:

  • do you see your code flashed in flash ROM (0x08000000)?
  • can you step in code and does it make sense?
  • can you check your linker script (if it would just assign to be loaded into SRAM and not generating code
    to be stored in flash ROM)?
  • Do you have any other example project which boots code from flash ROM?

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:

  1. code was not built in a way to be stored in flash (Linker Script)
  2. the startup code is missing or startup goes wrong

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.

I checked my project uses either FLASH or RAM by looking here.Ekran Alıntısı.PNG

  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 Ekran Alıntısı.PNG

This must be the problem causing everything goes bad. What should I do at this point. I am quite confused.

Thanks for your attention

@tjaekel @TDK 

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.

tjaekel_0-1735761405846.png

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.

 

 "Debug level" in the above had been already set as "-g3" and also optimization level was (none-O0). @tjaekel 

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):

tjaekel_0-1735766081884.png

Can you see the Reset_Handler code and step from there?

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.

Ekran Alıntısı.PNG

This is memory view.

Ekran Alıntısı.PNG

I replaced Reset_Handler with main in the debugger configuration, I can move forward step by step from here. @tjaekel