0

I am new to building projects from scratch with mcu's. I took an old project file that successfully runs in an eclipse/gdb build environment where the IDE does all the building for me and tried implementing my own build using open-ocd and the toolchain: arm-none-eabi. I was successful in flashing the device, however the board does not run the code. I was hoping that I could potentially be missing some obvious important file, but I have not come to that conclusion.

My main concern is that I do not have a proper set up for my start_up.c file or linker.ld file, though I have not found a reason to believe so. I am using the stm32L476 discovery board. Here is a link to the data sheet if anyone is interested: https://www.st.com/resource/en/reference_manual/dm00083560-stm32l47xxx-stm32l48xxx-stm32l49xxx-and-stm32l4axxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

My sources to my problem are here in github: https://github.com/landonbr/stm32-fun

1
  • 2
    No one wants to do a pull of your github to answer the question. Post relevant code right here. Commented Dec 24, 2020 at 3:49

1 Answer 1

1

I strongly recommend that you do not use C to bootstrap C. And strongly recommend not using structures across compile domains.

• 96 Kbyte mapped at address 0x2000 0000 (SRAM1) • 32 Kbyte located at address 0x1000 0000 with hardware parity check (SRAM2).

On STM32L49x/L4Ax devices, the SRAM2 is aliased at address 0x2004 0000, offering a continuous address space with the SRAM1.

This is an STM32L47 yes? So that does not apply.

08000000 <vector>:
 8000000:   20020000    andcs   r0, r2, r0
 8000004:   0800043b    stmdaeq r0, {r0, r1, r3, r4, r5, r10}
 8000008:   08000435    stmdaeq r0, {r0, r2, r4, r5, r10}
 800000c:   08000435    stmdaeq r0, {r0, r2, r4, r5, r10}

0x200000 = 128Kbytes. Try something small just to get started 0x20001000. Or go for the 96K. 0x20018000

It is not broken (well it can be depends on the register and field) but cleaner to do the read-modify-write separate from the register so the register only goes from one mode to another rather than switches modes twice.

GPIOB->MODER &= ~(3UL<<4);    // Clear mode bits​
GPIOB->MODER |= 1UL<<4;       // Set mode to output​


tmp = GPIOB->MODER
tmp &= ~(3UL<<4);    // Clear mode bits​
tmp |= 1UL<<4;       // Set mode to output​
GPIOB->MODER = tmp

It may be a good idea to do one thing at a time. Either just turn on an led or blink the led using a counter based delay (that is not dead code). Then later mess with buttons or timers or whatever.

Take a look at the gpio BSRR register instead of ODR. Makes life easier.

This is dead code,

    if(Upush%2!=0){
        GPIOE->ODR &= ~(1UL << 8);
        for(int i=125000; i!=0; i--){}
        GPIOE->ODR |= (1UL << 8);
        for (int i=125000; i!=0; i--){}
    }

It compiles into this basically

    if(Upush%2!=0){
        GPIOE->ODR &= ~(1UL << 8);
        GPIOE->ODR |= (1UL << 8);
    }

Which is too fast to see without a scope. And you cannot really determine the time in the loop so it is not 2 Hz.

In your case you did not optimize so that loop is in there it appears at least with the gnu I am using.

Granted you should start with this:

    while(1){
        GPIOE->BSRR = 1<<(8+16);
        for(volatile int i=125000; i!=0; i--){}
        GPIOE->BSRR = 1<<(8+ 0);
        for (volatile int i=125000; i!=0; i--){}
    }

as your main program after init of that gpio pin. Without any of the joystick buttons stuff. Get that working and insure that your basic skeleton is good, then add stuff to it. (note buttons are tricky/painful as you often want to debounce them. Likely not in this case, but in general)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.