# STM32 PWM only works correctly when I leave in two unused variables: StartUpCounter and HSEStatus

I'm using the stm32f3discovery board to try and generate the signal for a ws2812 light strip.

I've got src/system_stm32f30x.c, which I copied from the StdPeriph examples. I'm currently using the internal HSI, and the clock speed is 48MHz.

I'm using gcc-arm-none-eabi-4_8-2014q3 to compile.

If I leave src/system_stm32f30x.c as is, I get compiler warnings about unused variables, HSEStatus, and StartUpCounter, but my program works correctly. If I rename the variables to test1 and test2, it still works as expected, so it appears that it doesn't matter what the variables are named, it just matters that they are taking up memory (I guess).

However, if I comment these variables in order to get rid of the warning, my program no longer works correctly. The first pulse of the PWM signal is either grossly too short, or way to long. It causes the first LED on my strip to flash erratically (though the rest of the LEDs are fine).

My code is here: https://github.com/synic/neoclock/tree/stm32f303

What could it be?

• That typically means you have something writing to the wrong memory locations, and those unused variables serve as a buffer to protect. You can try setting them to magic values and checking later to see if they have been changed. (iirc, the _IO macro includes volatile). – Chris Stratton Oct 2 '14 at 15:27
• I think something is more fundamentally wrong with your build. If the variables are unused, it should be because their use is excluded by the preprocessor directives, in which case looking at the directives in your source they shouldn't even be seen to generate a warning. When I get that suspicious I start putting #warning (or even intentional syntax errors) in various places in the code to absolutely prove what is and isn't being processed by the compiler. – Chris Stratton Oct 2 '14 at 15:36
• I've done a watch -l StartUpCounter in gdb, and after that it basically breaks at every line in setup_gpio. Does this mean that memory is accessed every time? – synic Oct 2 '14 at 16:47
• It may just mean gdb is confused. If those are stack variables (as at first glance it appears they should be, if _IO is only volatile and not static) then the memory will only belong to them when inside the function, and may have other legitimate uses at other times. If they are globals, then it suggests some sort of memory corruption. Can you arm-whatever-objdump -d the file and post the implementation of the initialization function where they appear in your git? – Chris Stratton Oct 2 '14 at 17:18
• You code won't build since it's missing a lot of the header files, but it looks like declaring those volatile stack variables has the effect of zero initializing some memory a bit beyond two function calls down the stack. Your gpio initialization routine would be at the same stack depth. I can't see any obvious place where you are assuming the initial value of a stack variable, but if you are that could be an explanation. Granted, the memory was supposed to be zero-initialized just before this. I'm curious though what happens if you give these "unused" variables non-zero values. – Chris Stratton Oct 2 '14 at 19:52

Is PLL_SOURCE_HSI #defined in your code?

In system_stm32f30x.c, it looks like HSEStatus, and StartUpCounter should never be defined IFF your code is using the HSI oscillator.

Their definition is in the code:

#if defined (PLL_SOURCE_HSI)
...
#else
#if defined (PLL_SOURCE_HSE)
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;


So, it appears that something is undefine-ing PLL_SOURCE_HSI, and hence allowing StartUpCounter and HSEStatus to be defined.

I can't see anything in the source file src/system_stm32f30x.c to cause that.

So either:

1. the src/system_stm32f30x.c file at github is not the one being used in your build, or
2. your build is somehow causing PLL_SOURCE_HSI to become undefined and PLL_SOURCE_HSE to be defined (which seems unlikely to get both), or
3. the include file stm32f30x.h contains a syntax error which is causing some of this.

1 and 3 seem more likely.

Those two variables are local to SetSysClock. So their names can be safely changed.

Commenting out their definition should cause the compile of that source file to fail.

If the build is producing a program, then src/system_stm32f30x.c is not part of the program, or an old object is being used, or their is an inconsistency in the question.

If the HSI oscillator is being used in one case, and not in another, it is plausible that the PWM period is inconsistent.

• Sorry, yes, I had the wrong file committed (some of my earlier debugging attempts). It is now back to what it was before. Those two variables were defined at the beginning of the SetSysClock function. – synic Oct 2 '14 at 16:35
• Someone in the stm32 channel suggested I try using __attribute__((aligned(4))) on the struct that contains dma_buffer, however that seems to have produced no changes. – synic Oct 2 '14 at 16:36
• @synic - So, when you comment out those two variables, does the code compile? – gbulmer Oct 2 '14 at 16:38
• Yup, it compiles, but I think that's because where they are accessed is enclosed in #defines. I ma using PLL_SOURCE_HSI, so the code later in the function that references those two variables is never compiled. – synic Oct 2 '14 at 16:39
• @synic - There definition,  __IO uint32_t StartUpCounter = 0, HSEStatus = 0; is not " enclosed in #defines". There definitions, and all the code that uses them are enclosed in #if defined (PLL_SOURCE_HSI) ... #else #if defined (PLL_SOURCE_HSE) as I wrote in my answer. #define and #if defined(...) are very different. So, if you do not 'comment them out' have the compiler warnings gone away? – gbulmer Oct 2 '14 at 16:59