\ Program Name: timer.fs \ Date: 2016 \ Copyright 2017 t.porter , licensed under the GPL \ For Mecrisp-Stellaris by Matthias Koch \ Chip: STM32F051 \ Board: STM32F0 Discovery Board \ Terminal: e4thcom, Copyright (C) 2013-2017 Manfred Mahlow (GPL'd) https://wiki.forth-ev.de/doku.php/en:projects:e4thcom \ Clock: 8 Mhz using the internal STM32F051 RC clock, unless otherwise stated \ All register names are CMSIS-SVD compliant \ Note: gpio a,b,c,d,e, and uart1 are enabled by Mecrisp-Stellaris core as default. \ \ This Program : \ * measures elapsed time using the SYSTICK. \ * Flashes the BLUE led every second by counting 1000 systicks \ * A 1mS marker pulse is available on PB2 \ \ Registers Used:- As defined below \ timer.fs is self contained, no other files are required \ To be done: modify the code to run from Flash after a reboot. \ ------------------------------------------------------------------------------------------------------ \ Define Systick memory mapping as its not in CMSIS-SVD $E000E010 constant STK_CSR \ SysTick control and status register. R/W reset value = $00000000 $E000E014 constant STK_RVR \ SysTick reload value register. R/W reset value = 6000 (6MHz clock) for the STM32F0 $E000E018 constant STK_CVR \ SysTick current value register. R/W value unknown $E000E01C constant STK_CALIB \ SysTick calibration value register. Read Only, $40001770 for the STM32F0 \ Define other regs $48000400 constant GPIOB_MODER ( GPIO port mode register ) $48000800 constant GPIOC_MODER ( GPIO port mode register ) $48000418 constant GPIOB_BSRR ( GPIO port bit set/reset register ) $48000814 constant GPIOC_ODR \ Variables 0 variable second_counter 0 variable ms_counter \ can count to 32 bits or -> $ffffffff u. = 4294967295 mS or 4294967 seconds, or 71582 minutes or 1193 hours. : INIT-SYSTICK %01 4 lshift GPIOB_MODER bis! \ set PB2 to push pull output for the Marker %01 8 2* lshift GPIOC_MODER bis! \ PC8 as output for F0 Disco LED 8080 STK_RVR ! \ systick calib for 1ms using internal 8mhz osc %101 STK_CSR bis! \ systick enable ; : marker-set \ 1mS pulse for scope at PB2 %1 2 lshift GPIOB_BSRR bis! \ set PB2 = 1 ; : marker-clear %1 18 lshift GPIOB_BSRR bis! \ clear PB2 ; : toggle-systick-led GPIOC_ODR @ 1 8 lshift xor GPIOC_ODR ! ; : systick-handler marker-set ms_counter @ 1+ ms_counter ! second_counter @ 1+ \ add one to the counter dup 1000 >= if \ If counter is > = 1000 ... toggle-systick-led \ blink the LED at 1s rate drop \ drop the counter value of 1000 from the stack 0 \ put 0 on the stack to load in the counter after the 'then' then second_counter ! \ reset the counter to zero marker-clear ; ' systick-handler irq-systick ! \ This 'hooks' the systick-handler word (above) to the systick irq ENABLE-SYSTICK-INTERRUPT \ enable it last : delay ( delay-value -- elapsed-time ) 0 ms_counter ! \ reset the ms_counter to zero 0 DO LOOP \ the simple delay loop to be timed ." = " ms_counter @ . \ this will be updated by the systick-handler every systick and we just read it when the delay finishes ." milliseconds " cr ; INIT-SYSTICK \ ~~~~~~~~~~ Screenshots ~~~~~~~~~~~~ \ 10000 delay = 6 milliseconds \ 1000000 delay = 625 milliseconds \ 10000000 delay = 6256 milliseconds