2024-09-17 08:33 AM
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
Solved! Go to Solution.
2024-09-19 09:42 AM
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);
2024-09-17 08:36 AM
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.
2024-09-17 08:37 AM - edited 2024-09-17 10:29 AM
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.
2024-09-19 07:26 AM
Hi @SofLit ! I have now managed to get GDB up and running, and these are the contents of my registers:
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?
Thanks for any further assistance you can render me.
2024-09-19 09:42 AM
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);
2024-09-20 05:27 AM
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?
2024-09-20 05:42 AM
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.
2024-09-20 06:13 AM
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.