summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-05-01 08:58:17 -0700
committerKeith Packard <keithp@keithp.com>2013-05-07 20:08:01 -0700
commit091582c446319fe4a79154153ece5372b2faec83 (patch)
treea0b16053cc636cac751129db75e3cdc20fe857d1
parentb7b0ddfddee3f8e21f21d67cd9f522fa50777265 (diff)
altos: Use SYSTICK on STM32L
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>
-rw-r--r--src/stm/ao_arch.h1
-rw-r--r--src/stm/ao_timer.c40
-rw-r--r--src/stm/registers.ld2
-rw-r--r--src/stm/stm32l.h18
4 files changed, 30 insertions, 31 deletions
diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h
index 007f7e2e..27a942f2 100644
--- a/src/stm/ao_arch.h
+++ b/src/stm/ao_arch.h
@@ -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
diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c
index 8b7c2327..5976eb3f 100644
--- a/src/stm/ao_timer.c
+++ b/src/stm/ao_timer.c
@@ -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
diff --git a/src/stm/registers.ld b/src/stm/registers.ld
index 95a86e35..8318c75a 100644
--- a/src/stm/registers.ld
+++ b/src/stm/registers.ld
@@ -44,6 +44,8 @@ stm_tim4 = 0x40000800;
stm_tim3 = 0x40000400;
stm_tim2 = 0x40000000;
+stm_systick = 0xe000e010;
+
stm_nvic = 0xe000e100;
stm_scb = 0xe000ed00;
diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h
index 1d636037..5c0748a6 100644
--- a/src/stm/stm32l.h
+++ b/src/stm/stm32l.h
@@ -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 {