Skip to content

Commit b50cdb5

Browse files
committed
stm32f0: systick_blink: Robustness and correctness fixes
Update documentation and comments in code to reflect reality. Ensure that GPIO pin output speed is actually set, to ensure that 48Mhz sysclk output is functional. Actually set AF, instead of relying on reset values. Replace the systick code, the core of this example, with some code that has less traps and surprises. Instead of trying to get a direct interrupt x times per second, and reguarly running into problems with the 24 bit counter limit, use a method that triggers an interrupt every x ms instead. Tested MCO and blink rates with a logic analyser, properly verified working now :)
1 parent dfc4763 commit b50cdb5

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

examples/stm32/f0/stm32f0-discovery/systick_blink/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ to debug the PLL clock setup by scope.
1010

1111
| Port | Function | Description |
1212
| ----- | -------- | ------------------------ |
13-
| `PA9` | `(MCO)` | Internal reference clock |
13+
| `PA8` | `(MCO)` | Internal reference clock |

examples/stm32/f0/stm32f0-discovery/systick_blink/systick_blink.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,19 @@ void sys_tick_handler(void)
3030
gpio_toggle(GPIOC, GPIO8);
3131
}
3232

33-
/* Set up timer to fire freq times per second */
34-
static void systick_setup(int freq)
33+
/*
34+
* Set up timer to fire every x milliseconds
35+
* This is a unusual usage of systick, be very careful with the 24bit range
36+
* of the systick counter! You can range from 1 to 2796ms with this.
37+
*/
38+
static void systick_setup(int xms)
3539
{
36-
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
40+
/* div8 per ST, stays compatible with M3/M4 parts, well done ST */
41+
systick_set_clocksource(STK_CSR_CLKSOURCE_EXT);
3742
/* clear counter so it starts right away */
3843
STK_CVR = 0;
3944

40-
systick_set_reload(rcc_ahb_frequency / freq);
45+
systick_set_reload(rcc_ahb_frequency / 8 / 1000 * xms);
4146
systick_counter_enable();
4247
systick_interrupt_enable();
4348
}
@@ -49,23 +54,23 @@ static void clock_setup(void)
4954

5055
/* Enable clocks to the GPIO subsystems */
5156
rcc_periph_clock_enable(RCC_GPIOC);
52-
rcc_periph_clock_enable(RCC_GPIOA);
5357
}
5458

5559
static void gpio_setup(void)
5660
{
57-
/* Select pin functions. PC8/PC9 are the two LEDs on the
58-
STM32F0DISCOVERY board. */
59-
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8 | GPIO9);
60-
61-
/* set GPIOA to AF 0 */
62-
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8);
61+
/* Set blue led (PC8) as output */
62+
gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8);
6363
}
6464

6565
static void mco_setup(void)
6666
{
67-
/* Enable system clock output on pin PA8 (so it can be checked with a
68-
scope) */
67+
/* PA8 to AF 0 for MCO */
68+
rcc_periph_clock_enable(RCC_GPIOA);
69+
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8);
70+
gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO8);
71+
gpio_set_af(GPIOA, 0, GPIO8);
72+
73+
/* clock output on pin PA8 (allows checking with scope) */
6974
rcc_set_mco(RCC_CFGR_MCO_SYSCLK);
7075
}
7176

@@ -75,8 +80,8 @@ int main(void)
7580
gpio_setup();
7681
mco_setup();
7782

78-
/* setup systick to generate 2 LED flashes per second */
79-
systick_setup(8);
83+
/* 125ms ticks => 250ms period => 4Hz blinks */
84+
systick_setup(125);
8085

8186
/* Do nothing in main loop */
8287
while (1);

0 commit comments

Comments
 (0)