aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-03-20 17:44:34 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-04-11 16:56:54 -0400
commit21468a69ca2e7ff9a5c7ffc03c608a24f1412d64 (patch)
tree30d2abf224ca9adbc07b0fcdd1eb1b5a7d0541dd
parentc122d16c71d2aa04baa8b4b5a5df7faed93240fb (diff)
downloadlibrambutan-21468a69ca2e7ff9a5c7ffc03c608a24f1412d64.tar.gz
librambutan-21468a69ca2e7ff9a5c7ffc03c608a24f1412d64.zip
[FIXME] Resurrect boards.cpp for F2 and F1.
FIXME: - F1 support currently appears to be failing in start_c.c, for some unknown reason. This will need to get sorted out later. Add a new wirish namespace, and a sub-namespace wirish::priv::. Put a bunch of board setup routines in this namespace, and declare them in new wirish/boards_private.h. boards.cpp uses this to perform initialization tasks in a portable way, with two new boards_setup.cpp files under wirish/stm32f1 and wirish/stm32f2 handling the series-specific details. Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
-rw-r--r--wirish/boards.cpp167
-rw-r--r--wirish/boards_private.h59
-rw-r--r--wirish/include/wirish/boards.h5
-rw-r--r--wirish/rules.mk22
-rw-r--r--wirish/stm32f1/boards_setup.cpp141
-rw-r--r--wirish/stm32f2/boards_setup.cpp75
6 files changed, 363 insertions, 106 deletions
diff --git a/wirish/boards.cpp b/wirish/boards.cpp
index 5d5ecb5..7d783db 100644
--- a/wirish/boards.cpp
+++ b/wirish/boards.cpp
@@ -25,49 +25,55 @@
*****************************************************************************/
/**
- * @brief Generic board initialization routines.
+ * @file boards.cpp
+ * @brief Generic board routines.
*
* This file is mostly interesting for the init() function, which
* configures Flash, the core sytem clocks, and a variety of other
* available peripherals on the board so the rest of Wirish doesn't
* have to turn things on before using them.
*
- * Prior to returning, init() calls boardInit(), which allows boards
- * to perform any initialization they need to.
+ * How init() does this is chip-specific. See the chip-specific pieces
+ * of Wirish (under e.g. wirish/stm32f1/, wirish/stmf32f2) for
+ * details.
*
- * Specifically how init() works varies across boards and MCUs.
+ * Finally, prior to returning, init() calls boardInit(), which allows
+ * boards to perform any initialization they need to. This file
+ * includes a weak no-op definition of boardInit(), so boards that
+ * don't need any special initialization don't have to define their
+ * own.
*/
#include <wirish/boards.h>
-
#include <libmaple/flash.h>
-#include <libmaple/rcc.h>
#include <libmaple/nvic.h>
#include <libmaple/systick.h>
-#include <libmaple/gpio.h>
-#include <libmaple/adc.h>
-#include <libmaple/timer.h>
-#include <libmaple/usb_cdcacm.h>
+#include "boards_private.h"
+
+static void setup_flash(void);
+static void setup_clocks(void);
+static void setup_nvic(void);
-static void setupFlash(void);
-static void setupClocks(void);
-static void setupNVIC(void);
-static void setupADC(void);
-static void setupTimers(void);
+/*
+ * Exported functions
+ */
void init(void) {
- setupFlash();
- setupClocks();
- setupNVIC();
+ setup_flash();
+ setup_clocks();
+ setup_nvic();
systick_init(SYSTICK_RELOAD_VAL);
- gpio_init_all();
- afio_init();
- setupADC();
- setupTimers();
- usb_cdcacm_enable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT);
+ wirish::priv::board_setup_gpio();
+ wirish::priv::board_setup_adc();
+ wirish::priv::board_setup_timers();
+ wirish::priv::board_setup_usb();
boardInit();
}
+/* Provide a default boardInit(). */
+__attribute__((weak)) void boardInit(void) {
+}
+
/* You could farm this out to the files in boards/ if e.g. it takes
* too long to test on Maple Native (all those FSMC pins...). */
bool boardUsesPin(uint8 pin) {
@@ -79,24 +85,56 @@ bool boardUsesPin(uint8 pin) {
return false;
}
-static void setupFlash(void) {
- flash_enable_prefetch();
+/*
+ * Auxiliary routines
+ */
+
+static void setup_flash(void) {
+ // Turn on as many Flash "go faster" features as
+ // possible. flash_enable_features() just ignores any flags it
+ // can't support.
+ flash_enable_features(FLASH_PREFETCH | FLASH_ICACHE | FLASH_DCACHE);
+ // Configure the wait states, assuming we're operating at "close
+ // enough" to 3.3V.
flash_set_latency(FLASH_SAFE_WAIT_STATES);
}
-/*
- * 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.
- */
-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);
+static void setup_clocks(void) {
+ // Turn on HSI. We'll switch to and run off of this while we're
+ // setting up the main PLL.
+ rcc_turn_on_clk(RCC_CLK_HSI);
+
+ // Turn off and reset the clock subsystems we'll be using, as well
+ // as the clock security subsystem (CSS). Note that resetting CFGR
+ // to its default value of 0 implies a switch to HSI for SYSCLK.
+ RCC_BASE->CFGR = 0x00000000;
+ rcc_disable_css();
+ rcc_turn_off_clk(RCC_CLK_PLL);
+ rcc_turn_off_clk(RCC_CLK_HSE);
+ wirish::priv::board_reset_pll();
+ // Clear clock readiness interrupt flags and turn off clock
+ // readiness interrupts.
+ RCC_BASE->CIR = 0x00000000;
+
+ // Enable HSE, and wait until it's ready.
+ rcc_turn_on_clk(RCC_CLK_HSE);
+ while (!rcc_is_clk_ready(RCC_CLK_HSE))
+ ;
+
+ // Configure AHBx, APBx, etc. prescalers and the main PLL.
+ wirish::priv::board_setup_clock_prescalers();
+ rcc_configure_pll(&wirish::priv::board_pll_cfg);
+
+ // Enable the PLL, and wait until it's ready.
+ rcc_turn_on_clk(RCC_CLK_PLL);
+ while(!rcc_is_clk_ready(RCC_CLK_PLL))
+ ;
+
+ // Finally, switch to the now-ready PLL as the main clock source.
+ rcc_switch_sysclk(RCC_CLKSRC_PLL);
}
-static void setupNVIC() {
+static void setup_nvic(void) {
#ifdef VECT_TAB_FLASH
nvic_init(USER_ADDR_ROM, 0);
#elif defined VECT_TAB_RAM
@@ -107,60 +145,3 @@ static void setupNVIC() {
#error "You must select a base address for the vector table."
#endif
}
-
-static void adcDefaultConfig(const adc_dev* dev);
-
-static void setupADC() {
- rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6);
- adc_foreach(adcDefaultConfig);
-}
-
-static void timerDefaultConfig(timer_dev*);
-
-static void setupTimers() {
- timer_foreach(timerDefaultConfig);
-}
-
-static void adcDefaultConfig(const adc_dev *dev) {
- adc_init(dev);
-
- adc_set_extsel(dev, ADC_SWSTART);
- adc_set_exttrig(dev, true);
-
- adc_enable(dev);
- adc_calibrate(dev);
- adc_set_sample_rate(dev, ADC_SMPR_55_5);
-}
-
-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);
-}
diff --git a/wirish/boards_private.h b/wirish/boards_private.h
new file mode 100644
index 0000000..a4101c9
--- /dev/null
+++ b/wirish/boards_private.h
@@ -0,0 +1,59 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2012 LeafLabs, LLC.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *****************************************************************************/
+
+/**
+ * @file wirish/boards_private.h
+ * @author Marti Bolivar <mbolivar@leaflabs.com>
+ * @brief Private board support header.
+ */
+
+#ifndef _WIRISH_BOARDS_PRIVATE_H_
+#define _WIRISH_BOARDS_PRIVATE_H_
+
+namespace wirish {
+ namespace priv {
+
+ /*
+ * Chip-specific initialization data
+ */
+
+ extern rcc_pll_cfg board_pll_cfg;
+
+ /*
+ * Chip-specific initialization routines and helper functions.
+ */
+
+ void board_reset_pll(void);
+ void board_setup_clock_prescalers(void);
+ void board_setup_gpio(void);
+ void board_setup_adc(void);
+ void board_setup_timers(void);
+ void board_setup_usb(void);
+
+ }
+}
+
+#endif
diff --git a/wirish/include/wirish/boards.h b/wirish/include/wirish/boards.h
index e708f79..c762542 100644
--- a/wirish/include/wirish/boards.h
+++ b/wirish/include/wirish/boards.h
@@ -29,11 +29,6 @@
* @author Bryan Newbold <bnewbold@leaflabs.com>,
* Marti Bolivar <mbolivar@leaflabs.com>
* @brief Board-specific pin information.
- *
- * To add a new board type, add a new pair of files to
- * /wirish/boards/, update the section below with a new "BOARD" type,
- * and update /wirish/rules.mk to include your boards/your_board.cpp
- * file in the top-level Makefile build.
*/
#ifndef _WIRISH_BOARDS_H_
diff --git a/wirish/rules.mk b/wirish/rules.mk
index c72e60f..17c4d05 100644
--- a/wirish/rules.mk
+++ b/wirish/rules.mk
@@ -4,22 +4,26 @@ dirstack_$(sp) := $(d)
d := $(dir)
BUILDDIRS += $(BUILD_PATH)/$(d)
-# Board config -- TODO allow user override
-# WIRISH_BOARD_PATH := boards/$(BOARD)
-# BUILDDIRS += $(BUILD_PATH)/$(d)/$(WIRISH_BOARD_PATH)
+# Add board directory and MCU-specific directory to BUILDDIRS. These
+# are in subdirectories, but they're logically part of the Wirish
+# submodule.
+WIRISH_BOARD_PATH := boards/$(BOARD)
+BUILDDIRS += $(BUILD_PATH)/$(d)/$(WIRISH_BOARD_PATH)
+BUILDDIRS += $(BUILD_PATH)/$(d)/$(MCU_SERIES)
-# WIRISH_INCLUDES := -I$(d)/include -I$(d)/$(WIRISH_BOARD_PATH)/include
+# Safe includes for Wirish.
+WIRISH_INCLUDES := -I$(d)/include -I$(d)/$(WIRISH_BOARD_PATH)/include
-# Local flags
-CFLAGS_$(d) := $(LIBMAPLE_INCLUDES)
+# Local flags. Add -I$(d) to allow for private includes.
+CFLAGS_$(d) := $(LIBMAPLE_INCLUDES) $(WIRISH_INCLUDES) -I$(d)
# Local rules and targets
-
sSRCS_$(d) := start.S
cSRCS_$(d) := start_c.c
+cppSRCS_$(d) := boards.cpp
+# TODO: test these on F2 and put them back in:
# cppSRCS_$(d) := wirish_math.cpp \
# Print.cpp \
-# boards.cpp \
# HardwareSerial.cpp \
# HardwareSPI.cpp \
# HardwareTimer.cpp \
@@ -31,7 +35,9 @@ cSRCS_$(d) := start_c.c
# pwm.cpp \
# ext_interrupts.cpp \
# wirish_digital.cpp
+# TODO: Put this back in once we've got the necessary libmaple support back.
# cppSRCS_$(d) += $(WIRISH_BOARD_PATH)/board.cpp
+cppSRCS_$(d) += $(MCU_SERIES)/boards_setup.cpp
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
diff --git a/wirish/stm32f1/boards_setup.cpp b/wirish/stm32f1/boards_setup.cpp
new file mode 100644
index 0000000..4ee292a
--- /dev/null
+++ b/wirish/stm32f1/boards_setup.cpp
@@ -0,0 +1,141 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2012 LeafLabs, LLC.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+*****************************************************************************/
+
+/**
+ * @file wirish/stm32f1/boards_setup.cpp
+ * @author Marti Bolivar <mbolivar@leaflabs.com>
+ * @brief STM32F1 chip setup.
+ */
+
+#include <libmaple/rcc.h>
+#include <libmaple/gpio.h>
+#include <libmaple/adc.h>
+#include <libmaple/timer.h>
+#include <libmaple/usb_cdcacm.h>
+
+#include <board/board.h>
+
+/* FIXME: Reintroduce all "#if 0"'ed blocks once libmaple provides
+ * these definitions again. */
+
+namespace wirish {
+ namespace priv {
+
+ static stm32f1_rcc_pll_data pll_data = {RCC_PLLMUL_9};
+ rcc_pll_cfg board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data};
+
+#if 0
+ static void config_adc(const adc_dev* dev);
+ static void config_timer(timer_dev*);
+#endif
+
+ void board_reset_pll(void) {
+ // TODO
+ }
+
+ void board_setup_clock_prescalers(void) {
+ 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);
+ }
+
+ void board_setup_gpio(void) {
+ gpio_init_all();
+ // Initialize AFIO here, too, so peripheral remaps and external
+ // interrupts work out of the box.
+ afio_init();
+ }
+
+ void board_setup_adc(void) {
+#if 0
+ rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6);
+ adc_foreach(config_adc);
+#endif
+ }
+
+ void board_setup_timers(void) {
+#if 0
+ timer_foreach(config_timer);
+#endif
+ }
+
+ void board_setup_usb(void) {
+#if 0
+ usb_cdcacm_enable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT);
+#endif
+ }
+
+ /*
+ * Auxiliary routines
+ */
+
+#if 0
+ static void config_adc(const adc_dev *dev) {
+ adc_init(dev);
+
+ adc_set_extsel(dev, ADC_SWSTART);
+ adc_set_exttrig(dev, true);
+
+ adc_enable(dev);
+ adc_calibrate(dev);
+ adc_set_sample_rate(dev, ADC_SMPR_55_5);
+ }
+
+ static void config_timer(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);
+ }
+#endif
+ }
+}
diff --git a/wirish/stm32f2/boards_setup.cpp b/wirish/stm32f2/boards_setup.cpp
new file mode 100644
index 0000000..b3c690c
--- /dev/null
+++ b/wirish/stm32f2/boards_setup.cpp
@@ -0,0 +1,75 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2012 LeafLabs, LLC.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *****************************************************************************/
+
+/**
+ * @file wirish/stm32f2/boards_setup.cpp
+ * @author Marti Bolivar <mbolivar@leaflabs.com>
+ * @brief STM32F2 chip setup.
+ */
+
+#include <libmaple/rcc.h>
+#include <libmaple/gpio.h>
+
+#define PLL_Q 5
+#define PLL_P 2
+#define PLL_N 240
+#define PLL_M 25
+static stm32f2_rcc_pll_data pll_data = {PLL_Q, PLL_P, PLL_N, PLL_M};
+
+namespace wirish {
+ namespace priv {
+ rcc_pll_cfg board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data};
+
+ void board_reset_pll(void) {
+ // Set PLLCFGR to its reset value.
+ RCC_BASE->PLLCFGR = 0x24003010; // FIXME lose the magic number.
+ }
+
+ void board_setup_clock_prescalers(void) {
+ rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1);
+ rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_4);
+ rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_2);
+ }
+
+ void board_setup_gpio(void) {
+ gpio_init_all();
+ }
+
+ void board_setup_adc(void) {
+ // TODO
+ }
+
+ void board_setup_timers(void) {
+ // TODO
+ }
+
+ void board_setup_usb(void) {
+ // TODO
+ }
+
+ }
+}
+