aboutsummaryrefslogtreecommitdiffstats
path: root/wirish
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2012-03-26 22:17:47 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2012-04-11 16:56:56 -0400
commit28825b6a2f66b0329229185eb9cbd9004fae4b1b (patch)
treee9714efb41196c4492b68ff878974d01981708cd /wirish
parent7a400b065167beda0a1a9c642954e08581bc0c29 (diff)
downloadlibrambutan-28825b6a2f66b0329229185eb9cbd9004fae4b1b.tar.gz
librambutan-28825b6a2f66b0329229185eb9cbd9004fae4b1b.zip
Resurrect ADC support.
Standard refactoring: add series headers for F1 and F2, along with series adc.c files. There are some issues relating to adc_extsel_event to hammer out later, but this will do for now. We also add some new portability interfaces to libmaple/adc.h in order for Wirish to use the same code to initialize the ADCs at init() time. As usual, F1 is untested. Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
Diffstat (limited to 'wirish')
-rw-r--r--wirish/boards.cpp15
-rw-r--r--wirish/boards_private.h12
-rw-r--r--wirish/stm32f1/boards_setup.cpp39
-rw-r--r--wirish/stm32f2/boards_setup.cpp32
4 files changed, 59 insertions, 39 deletions
diff --git a/wirish/boards.cpp b/wirish/boards.cpp
index 04b359f..54807d3 100644
--- a/wirish/boards.cpp
+++ b/wirish/boards.cpp
@@ -54,6 +54,7 @@
static void setup_flash(void);
static void setup_clocks(void);
static void setup_nvic(void);
+static void setup_adcs(void);
/*
* Exported functions
@@ -65,7 +66,7 @@ void init(void) {
setup_nvic();
systick_init(SYSTICK_RELOAD_VAL);
wirish::priv::board_setup_gpio();
- wirish::priv::board_setup_adc();
+ setup_adcs();
wirish::priv::board_setup_timers();
wirish::priv::board_setup_usb();
boardInit();
@@ -124,7 +125,7 @@ static void setup_clocks(void) {
// Configure AHBx, APBx, etc. prescalers and the main PLL.
wirish::priv::board_setup_clock_prescalers();
- rcc_configure_pll(&wirish::priv::board_pll_cfg);
+ rcc_configure_pll(&wirish::priv::w_board_pll_cfg);
// Enable the PLL, and wait until it's ready.
rcc_turn_on_clk(RCC_CLK_PLL);
@@ -146,3 +147,13 @@ static void setup_nvic(void) {
#error "You must select a base address for the vector table."
#endif
}
+
+static void adc_default_config(const adc_dev *dev) {
+ adc_enable_single_swstart(dev);
+ adc_set_sample_rate(dev, wirish::priv::w_adc_smp);
+}
+
+static void setup_adcs(void) {
+ adc_set_prescaler(wirish::priv::w_adc_pre);
+ adc_foreach(adc_default_config);
+}
diff --git a/wirish/boards_private.h b/wirish/boards_private.h
index a4101c9..e32f298 100644
--- a/wirish/boards_private.h
+++ b/wirish/boards_private.h
@@ -28,11 +28,18 @@
* @file wirish/boards_private.h
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief Private board support header.
+ *
+ * This file declares chip-specific variables and functions which
+ * determine how init() behaves. It is not part of the public Wirish
+ * API, and can change without notice.
*/
#ifndef _WIRISH_BOARDS_PRIVATE_H_
#define _WIRISH_BOARDS_PRIVATE_H_
+#include <libmaple/rcc.h>
+#include <libmaple/adc.h>
+
namespace wirish {
namespace priv {
@@ -40,7 +47,9 @@ namespace wirish {
* Chip-specific initialization data
*/
- extern rcc_pll_cfg board_pll_cfg;
+ extern rcc_pll_cfg w_board_pll_cfg;
+ extern adc_prescaler w_adc_pre;
+ extern adc_smp_rate w_adc_smp;
/*
* Chip-specific initialization routines and helper functions.
@@ -49,7 +58,6 @@ namespace wirish {
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);
diff --git a/wirish/stm32f1/boards_setup.cpp b/wirish/stm32f1/boards_setup.cpp
index 4ee292a..8e16009 100644
--- a/wirish/stm32f1/boards_setup.cpp
+++ b/wirish/stm32f1/boards_setup.cpp
@@ -28,11 +28,15 @@
* @file wirish/stm32f1/boards_setup.cpp
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F1 chip setup.
+ *
+ * This file controls how init() behaves on the STM32F1. Be very
+ * careful when changing anything here. Many of these values depend
+ * upon each other.
*/
-#include <libmaple/rcc.h>
+#include "boards_private.h"
+
#include <libmaple/gpio.h>
-#include <libmaple/adc.h>
#include <libmaple/timer.h>
#include <libmaple/usb_cdcacm.h>
@@ -45,12 +49,11 @@ 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};
+ rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data};
+ adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6;
+ adc_smp_rate w_adc_smp = ADC_SMPR_55_5;
-#if 0
- static void config_adc(const adc_dev* dev);
static void config_timer(timer_dev*);
-#endif
void board_reset_pll(void) {
// TODO
@@ -69,17 +72,8 @@ namespace wirish {
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) {
@@ -92,19 +86,8 @@ namespace wirish {
* 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) {
+#if 0
timer_adv_reg_map *regs = (dev->regs).adv;
const uint16 full_overflow = 0xFFFF;
const uint16 half_duty = 0x8FFF;
@@ -135,7 +118,7 @@ namespace wirish {
}
timer_resume(dev);
- }
#endif
+ }
}
}
diff --git a/wirish/stm32f2/boards_setup.cpp b/wirish/stm32f2/boards_setup.cpp
index b3c690c..e1bf1fd 100644
--- a/wirish/stm32f2/boards_setup.cpp
+++ b/wirish/stm32f2/boards_setup.cpp
@@ -28,11 +28,18 @@
* @file wirish/stm32f2/boards_setup.cpp
* @author Marti Bolivar <mbolivar@leaflabs.com>
* @brief STM32F2 chip setup.
+ *
+ * This file controls how init() behaves on the STM32F2. Be very
+ * careful when changing anything here. Many of these values depend
+ * upon each other.
*/
-#include <libmaple/rcc.h>
+#include "boards_private.h"
+
#include <libmaple/gpio.h>
+#include <wirish/wirish_types.h>
+// PLL configuration for 25 MHz external oscillator --> 120 MHz SYSCLK.
#define PLL_Q 5
#define PLL_P 2
#define PLL_N 240
@@ -41,7 +48,18 @@ 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};
+ // PLL clocked off of HSE, with above configuration data.
+ rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data};
+ // As f_APB2 = 60 MHz (see board_setup_clock_prescalers),
+ // we need f_ADC = f_PCLK2 / 2 to get the (maximum)
+ // f_ADC = 30 MHz.
+ adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_2;
+ // With clocks as specified here (i.e. f_ADC = 30 MHz), this
+ // ADC sample rate allows for error less than 1/4 LSB with a
+ // 50 KOhm input impedance, assuming an internal sample and
+ // hold capacitance C_ADC at most 8.8 pF. See Equation 1 and
+ // Table 61 in the F2 datasheet for more details.
+ adc_smp_rate w_adc_smp = ADC_SMPR_144;
void board_reset_pll(void) {
// Set PLLCFGR to its reset value.
@@ -49,8 +67,13 @@ namespace wirish {
}
void board_setup_clock_prescalers(void) {
+ // With f_SYSCLK = 120 MHz (as determined by board_pll_cfg),
+ //
+ // f_AHB = f_SYSCLK / 1 = 120 MHz
rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1);
+ // f_APB1 = f_AHB / 4 = 30 MHz
rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_4);
+ // f_APB2 = f_AHB / 2 = 60 MHz
rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_2);
}
@@ -58,10 +81,6 @@ namespace wirish {
gpio_init_all();
}
- void board_setup_adc(void) {
- // TODO
- }
-
void board_setup_timers(void) {
// TODO
}
@@ -72,4 +91,3 @@ namespace wirish {
}
}
-