altos: Use SYSTICK on STM32L
authorKeith Packard <keithp@keithp.com>
Wed, 1 May 2013 15:58:17 +0000 (08:58 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 8 May 2013 03:08:01 +0000 (20:08 -0700)
It's probably more power efficient than using one of the timers, and
it's certainly easier to configure.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/stm/ao_arch.h
src/stm/ao_timer.c
src/stm/registers.ld
src/stm/stm32l.h

index 007f7e2ed3ac85e675244dc547f20dac82cc78e9..27a942f219f42b6303820f8f4e77bb64e1ebefa1 100644 (file)
@@ -99,6 +99,7 @@ extern const uint32_t ao_radio_cal;
 #define AO_HCLK                (AO_SYSCLK / AO_AHB_PRESCALER)
 #define AO_PCLK1       (AO_HCLK / AO_APB1_PRESCALER)
 #define AO_PCLK2       (AO_HCLK / AO_APB2_PRESCALER)
+#define AO_SYSTICK     (AO_HCLK / 8)
 
 #if AO_APB1_PRESCALER == 1
 #define AO_TIM23467_CLK                AO_PCLK1
index 8b7c2327ff2bdd34f93e7f93a8351f0c3ff63a4f..5976eb3f6657b6882d8cbfc668524f646f8387f4 100644 (file)
@@ -31,14 +31,9 @@ volatile __data uint8_t      ao_data_interval = 1;
 volatile __data uint8_t        ao_data_count;
 #endif
 
-void
-ao_debug_out(char c);
-
-
-void stm_tim6_isr(void)
+void stm_systick_isr(void)
 {
-       if (stm_tim6.sr & (1 << STM_TIM67_SR_UIF)) {
-               stm_tim6.sr = 0;
+       if (stm_systick.csr & (1 << STM_SYSTICK_CSR_COUNTFLAG)) {
                ++ao_tick_count;
 #if HAS_TASK_QUEUE
                if (ao_task_alarm_tick && (int16_t) (ao_tick_count - ao_task_alarm_tick) >= 0)
@@ -81,33 +76,16 @@ ao_timer_set_adc_interval(uint8_t interval)
 
 #define TIMER_10kHz    ((AO_PCLK1 * TIMER_23467_SCALER) / 10000)
 
+#define SYSTICK_RELOAD (AO_SYSTICK / 100 - 1)
+
 void
 ao_timer_init(void)
 {
-       stm_nvic_set_enable(STM_ISR_TIM6_POS);
-       stm_nvic_set_priority(STM_ISR_TIM6_POS, AO_STM_NVIC_CLOCK_PRIORITY);
-
-       /* Turn on timer 6 */
-       stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_TIM6EN);
-
-       stm_tim6.psc = TIMER_10kHz;
-       stm_tim6.arr = 99;
-       stm_tim6.cnt = 0;
-
-       /* Enable update interrupt */
-       stm_tim6.dier = (1 << STM_TIM67_DIER_UIE);
-
-       /* Poke timer to reload values */
-       stm_tim6.egr |= (1 << STM_TIM67_EGR_UG);
-
-       stm_tim6.cr2 = (STM_TIM67_CR2_MMS_RESET << STM_TIM67_CR2_MMS);
-
-       /* And turn it on */
-       stm_tim6.cr1 = ((0 << STM_TIM67_CR1_ARPE) |
-                       (0 << STM_TIM67_CR1_OPM) |
-                       (1 << STM_TIM67_CR1_URS) |
-                       (0 << STM_TIM67_CR1_UDIS) |
-                       (1 << STM_TIM67_CR1_CEN));
+       stm_systick.rvr = SYSTICK_RELOAD;
+       stm_systick.cvr = 0;
+       stm_systick.csr = ((1 << STM_SYSTICK_CSR_ENABLE) |
+                          (1 << STM_SYSTICK_CSR_TICKINT) |
+                          (STM_SYSTICK_CSR_CLKSOURCE_HCLK_8 << STM_SYSTICK_CSR_CLKSOURCE));
 }
 
 void
index 95a86e358fc3f51019aa29b098271dd7034b12c0..8318c75a87a6330634b08ec6c3a71a5d3e778e97 100644 (file)
@@ -44,6 +44,8 @@ stm_tim4   = 0x40000800;
 stm_tim3   = 0x40000400;
 stm_tim2   = 0x40000000;
 
+stm_systick = 0xe000e010;
+
 stm_nvic   = 0xe000e100;
 
 stm_scb    = 0xe000ed00;
index 1d6360372e9a51c604bc059b88b8961f27ffc4fb..5c0748a6891dd3432b34329422bb745f42e41fef 100644 (file)
@@ -811,6 +811,24 @@ extern struct stm_lcd stm_lcd;
 #define STM_LCD_CLR_UDDC               (3)
 #define STM_LCD_CLR_SOFC               (1)
 
+/* The SYSTICK starts at 0xe000e010 */
+
+struct stm_systick {
+       vuint32_t       csr;
+       vuint32_t       rvr;
+       vuint32_t       cvr;
+       vuint32_t       calib;
+};
+
+extern struct stm_systick stm_systick;
+
+#define STM_SYSTICK_CSR_ENABLE         0
+#define STM_SYSTICK_CSR_TICKINT                1
+#define STM_SYSTICK_CSR_CLKSOURCE      2
+#define  STM_SYSTICK_CSR_CLKSOURCE_HCLK_8              0
+#define  STM_SYSTICK_CSR_CLKSOURCE_HCLK                        1
+#define STM_SYSTICK_CSR_COUNTFLAG      16
+
 /* The NVIC starts at 0xe000e100, so add that to the offsets to find the absolute address */
 
 struct stm_nvic {