cancel
Showing results for 
Search instead for 
Did you mean: 

Blink example for STM32L552 Nucleo board

krook
Associate II

Hi!

 

I am trying to run a simple blink example using the STM32L552 Nucleo board, but I can't seem to figure it out. Any help in figuring out what my problem is would be very helpful. I've tried looking at the data sheet to figure out what the SRAM-boundaries are etc, but I must have gotten something wrong.

I am using the CMSIS stuff. The program is simply supposed to blink on of the LEDs, but nothing happens.

Here is startup.c:

 

 

 

#define SRAM_START (0x20000000UL)
#define SRAM_SIZE (32U * 256U)
#define SRAM_END (SRAM_START + SRAM_SIZE)
#define STACK_POINTER_INIT_ADDRESS (SRAM_END)

#include <stdint.h>
#define VECTOR_SIZE_WORDS 464

void default_handler(void);
void reset_handler(void);

void nmi_handler(void) __attribute__((weak, alias("default_handler")));
void hard_handler(void) __attribute__((weak, alias("default_handler")));
void mem_handler(void) __attribute__((weak, alias("default_handler")));
void bus_handler(void) __attribute__((weak, alias("default_handler")));
void usage_handler(void) __attribute__((weak, alias("default_handler")));
void sv_handler(void) __attribute__((weak, alias("default_handler")));
void debug_handler(void) __attribute__((weak, alias("default_handler")));
void pend_handler(void) __attribute__((weak, alias("default_handler")));
void sys_handler(void) __attribute__((weak, alias("default_handler")));

uint32_t isr_vector[VECTOR_SIZE_WORDS] __attribute__((section(".isr_vector"))) = {
    STACK_POINTER_INIT_ADDRESS,
    (uint32_t)&reset_handler,
    (uint32_t)&nmi_handler,
    (uint32_t)&hard_handler,
    (uint32_t)&mem_handler,
    (uint32_t)&bus_handler,
    (uint32_t)&usage_handler,
    0,
    0,
    0,
    0,
    (uint32_t)&sv_handler,
    (uint32_t)&debug_handler,
    0,
    (uint32_t)&pend_handler,
    (uint32_t)&sys_handler,
    // add more handlers as wanted
};

void default_handler(void) {
    while(1);
}

extern uint32_t _etext, _sdata, _edata, _sbss, _ebss;
void main(void);

void reset_handler(void) {
    // Copy .data from FLASH to SRAM
    uint32_t data_size = (uint32_t)&_edata - (uint32_t)&_sdata;
    uint8_t *flash_data = (uint8_t*) &_etext;
    uint8_t *sram_data = (uint8_t*) &_sdata;
  
    for (uint32_t i = 0; i < data_size; i++)
    {
      sram_data[i] = flash_data[i];
    }

    // Zero-fill .bss section in SRAM
    uint32_t bss_size = (uint32_t)&_ebss - (uint32_t)&_sbss;
    uint8_t *bss = (uint8_t*) &_sbss;

    for (uint32_t i = 0; i < bss_size; i++)
    {
      bss[i] = 0;
    }
  
    main();
}

 

 

 

 And here is my main.c:

 

 

 

#include <stdint.h>
#include "stm32l5xx.h"

#define LED_PIN 9 // PA9 should be one of the LEDs!

void main(void) {
    // enable the peripheral clock
    RCC->AHB2ENR |= (1 << RCC_AHB2ENR_GPIOAEN_Pos);

    volatile uint32_t dummy;
    dummy = RCC->AHB2ENR;
    dummy = RCC->AHB2ENR;

    // set PA9 as output
    GPIOA->MODER |= (1 << GPIO_MODER_MODE9_Pos);
    
    // toggle the pin on and off
    while(1) {
        GPIOA->ODR ^= (1 << LED_PIN);
        for (uint32_t i = 0; i < 1000000; i++);
    }
}

 

 

 

 I've managed to put together this linker script by following a tutorial online:

 

 

 

ENTRY(reset_handler)

MEMORY
{
    FLASH (rx): ORIGIN = 0x8000000, LENGTH = 512K
    SRAM (rwx): ORIGIN = 0x20000000, LENGTH = 1024K
}

SECTIONS
{
    .isr_vector :
    {
        KEEP(*(.isr_vector))
    } >FLASH

    .text :
    {
        . = ALIGN(4);
        *(.text)
        *(.rodata)
        . = ALIGN(4);
        _etext = .;
    } >FLASH

    .data :
    {
        . = ALIGN(4);
        _sdata = .;
        *(.data)
        . = ALIGN(4);
        _edata = .;
    } >SRAM AT> FLASH

    .bss :
    {
        . = ALIGN(4);
        _sbss = .;
        *(.bss)
        . = ALIGN(4);
        _ebss = .;
    } >SRAM
}

 

 

 

 I manage to compile this without warning and flash my device using `openocd`, but the board is not blinking.

This document might be helpful -- it is from where I've collected information: file:///home/robert/Downloads/dm00346336-stm32l552xx-and-stm32l562xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf

1 ACCEPTED SOLUTION

Accepted Solutions

Hello,

MODER9 reset value is not 0, please check the STM32L5 reference manual,

Perhaps you need to reset the 2 bits before setting the value to 1:

GPIOA->MODER &= ~(GPIO_MODER_MODE9_Msk);
GPIOA->MODER |= (1 << GPIO_MODER_MODE9_Pos);

View solution in original post

7 REPLIES 7
krook
Associate II

Lol I didn't check that the link I posted was actually the correct one... this is of course the link that I wanted to provide: https://www.google.com/url?sa=t&source=web&rct=j&opi=89978449&url=https://www.st.com/resource/en/reference_manual/dm00346336-stm32l552xx-and-stm32l562xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf&ved=2ahUKEwjj0qzopsqIAxW2FBAIHfZXC9QQFnoECBQQAQ&usg=AOvVaw2Xwv5137qa2OFrClStJ4Xl

 

I've also attached the document to this reply. It is the STM32L552 reference manual.

SofLit
ST Employee

hello,

Need to check the registers content in the debugger versus what you are suspecting: check if the bits you set / reset are well set/reset in the registers.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Hi @SofLit ! I have now managed to get GDB up and running, and these are the contents of my registers:

  • The RCC register to enable AHB2 is at address 0x4002104c, and offset 0 has the GPIOA enable bit. The value as reported by GDB at that location is 0x00000001
  • I am also trying to designate PA9 as an output pin. GPIOA should be at address 0x42020000, and the mode register is at offset 0x00. The contents at address 0x42020000 is 0xabffffff
  • Finally, the output data register is at offset 0x14 from GPIOA (0x42020000). I set a watchpoint there, and I see that the value fluctuates between 0x00000200 and 0x00000000 with a second or two of delay. It seems as if this address changes value as I want it to, but it is just not actualised on the LED.

I am not sure what my take-away from this is. I wonder if the designation of PA9 as output is happening correctly. The documentation says that the reset value of port A is 0xabffffff. The operation on line 15 in my code is seemingly a no-op in that case?

Screenshot from 2024-09-19 16-24-45.png

Thanks for any further assistance you can render me.

Hello,

MODER9 reset value is not 0, please check the STM32L5 reference manual,

Perhaps you need to reset the 2 bits before setting the value to 1:

GPIOA->MODER &= ~(GPIO_MODER_MODE9_Msk);
GPIOA->MODER |= (1 << GPIO_MODER_MODE9_Pos);

That did not work, but I've done some more debugging now.

It appears as if any write to the `GPIOA->MODER` register isn't happening. That led me to believe that the block perhaps hadn't been enabled in the RCC register, so I looked what the contents of it were. If I set a breakpoint on line 20 and then read the RCC register, the value is `0x00000000`! It should be `0x00000001`, because the GPIOA enable register is on bit 0.

The very first thing my `main` is doing is to set that bit to 1, so I am not sure why this is not happening... Any guess?

@SofLit @Mike_ST 

Sorry, I was looking in the wrong location. I can now see that the RCC->AHB2ENR register gets the value `0x00000001`, which is correct! That should turn on the GPIOA block. However, the GPIOA->MODER register still gets the wrong value.

I have quickly tested your program on my board, it is blinking fine with the patch to reset the MODER bits.

What value do you have in the GPIOA_MODER register ?

Another THING you can check is whether you have the "Trust Zone" enabled in the option bytes of the chip and you can have a look at the GPIOA_SECFGR register.