aboutsummaryrefslogtreecommitdiffstats
path: root/wirish/wirish.cpp
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2011-03-22 16:59:29 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2011-03-24 07:25:14 -0400
commit61db54f52f32e63c895d775982fbcdcb67f2dde6 (patch)
treeb0513c712b5888ab0a4e6613fdee3db606b61aaf /wirish/wirish.cpp
parent6bc8cb7c1181e8005019e4ce1f2bea956c44e044 (diff)
downloadlibrambutan-61db54f52f32e63c895d775982fbcdcb67f2dde6.tar.gz
librambutan-61db54f52f32e63c895d775982fbcdcb67f2dde6.zip
Initial timer refactor.
Basic PWM works. Had some problems in testing that might be due to USART bugs. HardwareTimer has been removed from the build for now; I will re-implement it in terms of the new libmaple API, but consider it deprecated. Let's come up with something better. Servo is implemented in terms of HardwareTimer, so it also has been temporarily removed from the build. pwmWrite() likely got a little bit less inefficient due to indirection, but the PIN_MAPs shrank by a pointer per PinMapping.
Diffstat (limited to 'wirish/wirish.cpp')
-rw-r--r--wirish/wirish.cpp122
1 files changed, 84 insertions, 38 deletions
diff --git a/wirish/wirish.cpp b/wirish/wirish.cpp
index 65d0262..6dcb1b5 100644
--- a/wirish/wirish.cpp
+++ b/wirish/wirish.cpp
@@ -23,61 +23,107 @@
*****************************************************************************/
/**
- * @brief generic maple board bring up:
+ * @brief Generic Maple board initialization.
*
- * By default, we bring up all maple boards running on the stm32 to 72mhz,
- * clocked off the PLL, driven by the 8MHz external crystal.
- *
- * AHB and APB2 are clocked at 72MHz
- * APB1 is clocked at 36MHz
+ * By default, we bring up all Maple boards to 72MHz, clocked off the
+ * PLL, driven by the 8MHz external crystal. AHB and APB2 are clocked
+ * at 72MHz. APB1 is clocked at 36MHz.
*/
#include "wirish.h"
+
+#include "flash.h"
+#include "rcc.h"
+#include "nvic.h"
#include "systick.h"
#include "gpio.h"
-#include "nvic.h"
+#include "adc.h"
+#include "timer.h"
#include "usb.h"
-#include "rcc.h"
-#include "fsmc.h"
-#include "dac.h"
-#include "flash.h"
-#include "native_sram.h"
+static void setupFlash(void);
+static void setupClocks(void);
+static void setupADC(void);
+static void setupTimers(void);
+
+/**
+ * Board-wide initialization function. Called before main().
+ */
void init(void) {
- /* make sure the flash is ready before spinning the high speed clock up */
+ setupFlash();
+ setupClocks();
+ nvic_init();
+ systick_init(SYSTICK_RELOAD_VAL);
+ gpio_init_all();
+ afio_init();
+ setupADC();
+ setupTimers();
+ setupUSB();
+
+ BOARD_INIT;
+}
+
+static void setupFlash(void) {
flash_enable_prefetch();
flash_set_latency(FLASH_WAIT_STATE_2);
+}
-#ifdef BOARD_maple_native
- initNativeSRAM();
-#endif
-
- /* initialize clocks */
+/*
+ * Clock setup. Note that some of this only takes effect if we're
+ * running bare metal and the bootloader hasn't done it for us
+ * already.
+ *
+ * If you change this function, you MUST change the file-level Doxygen
+ * comment above.
+ */
+static void setupClocks() {
rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9);
rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1);
rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2);
rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1);
+}
- nvic_init();
- systick_init(SYSTICK_RELOAD_VAL);
- gpio_init_all();
- afio_init();
-
- /* Initialize the ADC for slow conversions, to allow for high
- impedance inputs. */
+/* TODO initialize more ADCs on high density boards. */
+static void setupADC() {
adc_init(ADC1, 0);
- adc_set_sample_rate(ADC1, ADC_SMPR_55_5);
-
- timer_init(TIMER1, 1);
- timer_init(TIMER2, 1);
- timer_init(TIMER3, 1);
- timer_init(TIMER4, 1);
-#ifdef STM32_HIGH_DENSITY
- timer_init(TIMER5, 1);
- timer_init(TIMER8, 1);
-#endif
- setupUSB();
+ adc_set_sample_rate(ADC1, ADC_SMPR_55_5); // for high impedance inputs
+}
- /* include the board-specific init macro */
- BOARD_INIT;
+static void timerDefaultConfig(timer_dev*);
+
+static void setupTimers() {
+ timer_foreach(timerDefaultConfig);
+}
+
+static void timerDefaultConfig(timer_dev *dev) {
+ timer_adv_reg_map *regs = (dev->regs).adv;
+ const uint16 full_overflow = 0xFFFF;
+ const uint16 half_duty = 0x8FFF;
+
+ timer_init(dev);
+ timer_pause(dev);
+
+ regs->CR1 = TIMER_CR1_ARPE;
+ regs->PSC = 1;
+ regs->SR = 0;
+ regs->DIER = 0;
+ regs->EGR = TIMER_EGR_UG;
+
+ switch (dev->type) {
+ case TIMER_ADVANCED:
+ regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF;
+ // fall-through
+ case TIMER_GENERAL:
+ timer_set_reload(dev, full_overflow);
+
+ for (int channel = 1; channel <= 4; channel++) {
+ timer_set_compare(dev, channel, half_duty);
+ timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE);
+ }
+ // fall-through
+ case TIMER_BASIC:
+ break;
+ }
+
+ timer_resume(dev);
}