aboutsummaryrefslogtreecommitdiffstats
path: root/wirish
diff options
context:
space:
mode:
Diffstat (limited to 'wirish')
-rw-r--r--wirish/HardwareSPI.cpp38
-rw-r--r--wirish/HardwareTimer.cpp18
-rw-r--r--wirish/Print.cpp12
-rw-r--r--wirish/boards.cpp110
-rw-r--r--wirish/boards/robotis_cm900/board.cpp (renamed from wirish/boards/cm900/board.cpp)8
-rw-r--r--wirish/boards/robotis_cm900/include/board/board.h (renamed from wirish/boards/cm900/include/board/board.h)2
-rw-r--r--wirish/boards/robotis_opencm904/board.cpp (renamed from wirish/boards/opencm904/board.cpp)5
-rw-r--r--wirish/boards/robotis_opencm904/include/board/board.h (renamed from wirish/boards/opencm904/include/board/board.h)0
-rw-r--r--wirish/boards/st_nucleo_f103rb/board.cpp (renamed from wirish/boards/nucleo/board.cpp)4
-rw-r--r--wirish/boards/st_nucleo_f103rb/include/board/board.h (renamed from wirish/boards/nucleo/include/board/board.h)6
-rw-r--r--wirish/boards/st_stm32f401cdiscovery/board.cpp177
-rw-r--r--wirish/boards/st_stm32f401cdiscovery/include/board/board.h127
-rw-r--r--wirish/boards/st_stm32vldiscovery/board.cpp (renamed from wirish/boards/VLDiscovery/board.cpp)4
-rw-r--r--wirish/boards/st_stm32vldiscovery/include/board/board.h (renamed from wirish/boards/VLDiscovery/include/board/board.h)4
-rw-r--r--wirish/boards_private.h13
-rw-r--r--wirish/include/wirish/ext_interrupts.h4
-rw-r--r--wirish/include/wirish/wirish.h9
-rw-r--r--wirish/include/wirish/wirish_math.h3
-rw-r--r--wirish/rules.mk33
-rw-r--r--wirish/stm32f2-f4/boards_setup.cpp (renamed from wirish/stm32f2/boards_setup.cpp)69
-rw-r--r--wirish/stm32f2-f4/util_hooks.c (renamed from wirish/stm32f2/util_hooks.c)36
-rw-r--r--wirish/stm32f2-f4/wirish_debug.cpp (renamed from wirish/stm32f2/wirish_debug.cpp)0
-rw-r--r--wirish/stm32f2-f4/wirish_digital.cpp (renamed from wirish/stm32f2/wirish_digital.cpp)0
23 files changed, 562 insertions, 120 deletions
diff --git a/wirish/HardwareSPI.cpp b/wirish/HardwareSPI.cpp
index 94985eb..1acba76 100644
--- a/wirish/HardwareSPI.cpp
+++ b/wirish/HardwareSPI.cpp
@@ -2,6 +2,7 @@
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
+ * Copyright 2014 Google, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -59,23 +60,32 @@ static void enable_device(spi_dev *dev,
spi_mode mode);
static const spi_pins board_spi_pins[] __FLASH__ = {
+#if BOARD_HAVE_SPI1
{BOARD_SPI1_NSS_PIN,
BOARD_SPI1_SCK_PIN,
BOARD_SPI1_MISO_PIN,
BOARD_SPI1_MOSI_PIN},
+#else
+ {0, 0, 0, 0},
+#endif
+#if BOARD_HAVE_SPI2
{BOARD_SPI2_NSS_PIN,
BOARD_SPI2_SCK_PIN,
BOARD_SPI2_MISO_PIN,
BOARD_SPI2_MOSI_PIN},
-#ifdef STM32_HIGH_DENSITY
+#else
+ {0, 0, 0, 0},
+#endif
+#if BOARD_HAVE_SPI3
{BOARD_SPI3_NSS_PIN,
BOARD_SPI3_SCK_PIN,
BOARD_SPI3_MISO_PIN,
BOARD_SPI3_MOSI_PIN},
+#else
+ {0, 0, 0, 0},
#endif
};
-
/*
* Constructor
*/
@@ -235,12 +245,26 @@ static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq);
static const spi_pins* dev_to_spi_pins(spi_dev *dev) {
switch (dev->clk_id) {
- case RCC_SPI1: return board_spi_pins;
- case RCC_SPI2: return board_spi_pins + 1;
-#ifdef STM32_HIGH_DENSITY
- case RCC_SPI3: return board_spi_pins + 2;
+ case RCC_SPI1:
+#if BOARD_HAVE_SPI1
+ return board_spi_pins;
+#else
+ return NULL;
+#endif
+ case RCC_SPI2:
+#if BOARD_HAVE_SPI2
+ return board_spi_pins + 1;
+#else
+ return NULL;
#endif
- default: return NULL;
+ case RCC_SPI3:
+#if BOARD_HAVE_SPI3
+ return board_spi_pins + 2;
+#else
+ return NULL;
+#endif
+ default:
+ return NULL;
}
}
diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp
index 4f68ad7..1d9fe61 100644
--- a/wirish/HardwareTimer.cpp
+++ b/wirish/HardwareTimer.cpp
@@ -2,6 +2,7 @@
* The MIT License
*
* Copyright (c) 2010 Bryan Newbold.
+ * Copyright 2014 Google, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -26,6 +27,7 @@
#include <wirish/HardwareTimer.h>
+#include <libmaple/stm32.h>
#include <libmaple/rcc.h>
#include <wirish/ext_interrupts.h> // for noInterrupts(), interrupts()
#include <wirish/wirish_math.h>
@@ -144,13 +146,27 @@ void HardwareTimer::refresh(void) {
/* -- Deprecated predefined instances -------------------------------------- */
+#if STM32_TIMER_MASK & (1 << 1)
HardwareTimer Timer1(1);
+#endif
+#if STM32_TIMER_MASK & (1 << 2)
HardwareTimer Timer2(2);
+#endif
+#if STM32_TIMER_MASK & (1 << 3)
HardwareTimer Timer3(3);
+#endif
+#if STM32_TIMER_MASK & (1 << 4)
HardwareTimer Timer4(4);
-#ifdef STM32_HIGH_DENSITY
+#endif
+#if STM32_TIMER_MASK & (1 << 5)
HardwareTimer Timer5(5);
+#endif
+#if STM32_TIMER_MASK & (1 << 6)
HardwareTimer Timer6(6);
+#endif
+#if STM32_TIMER_MASK & (1 << 7)
HardwareTimer Timer7(7);
+#endif
+#if STM32_TIMER_MASK & (1 << 8)
HardwareTimer Timer8(8);
#endif
diff --git a/wirish/Print.cpp b/wirish/Print.cpp
index f6bc0c6..cf0f74b 100644
--- a/wirish/Print.cpp
+++ b/wirish/Print.cpp
@@ -196,7 +196,7 @@ void Print::printNumber(unsigned long long n, uint8 base) {
* nextafter((double)numeric_limits<long long>::max(), 0.0) ~= 9.22337e+18
*
* This slightly smaller value was picked semi-arbitrarily. */
-#define LARGE_DOUBLE_TRESHOLD (9.1e18)
+#define LARGE_DOUBLE_TRESHOLD ((double)9.1e18)
/* THIS FUNCTION SHOULDN'T BE USED IF YOU NEED ACCURATE RESULTS.
*
@@ -211,7 +211,7 @@ void Print::printNumber(unsigned long long n, uint8 base) {
void Print::printFloat(double number, uint8 digits) {
// Hackish fail-fast behavior for large-magnitude doubles
if (abs(number) >= LARGE_DOUBLE_TRESHOLD) {
- if (number < 0.0) {
+ if (number < (double)0.0) {
print('-');
}
print("<large double>");
@@ -219,16 +219,16 @@ void Print::printFloat(double number, uint8 digits) {
}
// Handle negative numbers
- if (number < 0.0) {
+ if (number < (double)0.0) {
print('-');
number = -number;
}
// Simplistic rounding strategy so that e.g. print(1.999, 2)
// prints as "2.00"
- double rounding = 0.5;
+ double rounding = (double)0.5;
for (uint8 i = 0; i < digits; i++) {
- rounding /= 10.0;
+ rounding /= (double)10.0;
}
number += rounding;
@@ -244,7 +244,7 @@ void Print::printFloat(double number, uint8 digits) {
// Extract digits from the remainder one at a time
while (digits-- > 0) {
- remainder *= 10.0;
+ remainder *= (double)10.0;
int to_print = (int)remainder;
print(to_print);
remainder -= to_print;
diff --git a/wirish/boards.cpp b/wirish/boards.cpp
index 77a05de..6b0c74b 100644
--- a/wirish/boards.cpp
+++ b/wirish/boards.cpp
@@ -3,6 +3,7 @@
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011, 2012 LeafLabs, LLC.
+ * Copyright 2014 Google, Inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -45,6 +46,8 @@
* notice.
*/
+#pragma GCC diagnostic ignored "-Wunused-function"
+
#include <wirish/boards.h>
#include <libmaple/libmaple_types.h>
#include <libmaple/flash.h>
@@ -52,24 +55,16 @@
#include <libmaple/systick.h>
#include "boards_private.h"
-static void setup_flash(void);
-static void setup_clocks(void);
static void setup_nvic(void);
-static void setup_adcs(void);
-static void setup_timers(void);
-
-/*
- * Exported functions
- */
void init(void) {
- setup_flash();
- setup_clocks();
+ wirish::priv::board_setup_flash();
+ wirish::priv::board_setup_clocks();
setup_nvic();
systick_init(SYSTICK_RELOAD_VAL);
wirish::priv::board_setup_gpio();
- setup_adcs();
- setup_timers();
+ wirish::priv::board_setup_adcs();
+ wirish::priv::board_setup_timers();
wirish::priv::board_setup_usb();
wirish::priv::series_init();
boardInit();
@@ -91,20 +86,54 @@ bool boardUsesPin(uint8 pin) {
}
/*
- * Auxiliary routines
+ * These addresses are where usercode starts when a bootloader is
+ * present. If no bootloader is present, the user NVIC usually starts
+ * at the Flash base address, 0x08000000.
*/
+#if defined(BOOTLOADER_maple)
+#define USER_ADDR_ROM 0x08005000
+#elif defined(BOOTLOADER_robotis)
+#define USER_ADDR_ROM 0x08003000
+#endif
+#define USER_ADDR_RAM 0x20000C00
+extern char __text_start__;
+
+static void setup_nvic(void) {
+#ifdef VECT_TAB_FLASH
+ nvic_init(USER_ADDR_ROM, 0);
+#elif defined VECT_TAB_RAM
+ nvic_init(USER_ADDR_RAM, 0);
+#elif defined VECT_TAB_BASE
+ nvic_init((uint32)0x08000000, 0);
+#elif defined VECT_TAB_ADDR
+ // A numerically supplied value
+ nvic_init((uint32)VECT_TAB_ADDR, 0);
+#else
+ // Use the __text_start__ value from the linker script; this
+ // should be the start of the vector table.
+ nvic_init((uint32)&__text_start__, 0);
+#endif
+}
+
+/*
+ * Default implementations for some board-specific routines.
+ */
+
+namespace wirish {
+namespace priv {
-static void setup_flash(void) {
+__weak rcc_clk w_board_pll_in_clk = RCC_CLK_HSE;
+
+__weak void board_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_SAFE_WAIT_STATES is a hack that needs to go away.
flash_set_latency(FLASH_SAFE_WAIT_STATES);
}
-static void setup_clocks(void) {
+__weak void board_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);
@@ -115,15 +144,17 @@ static void setup_clocks(void) {
RCC_BASE->CFGR = 0x00000000;
rcc_disable_css();
rcc_turn_off_clk(RCC_CLK_PLL);
- rcc_turn_off_clk(RCC_CLK_HSE);
+ if (w_board_pll_in_clk != RCC_CLK_HSI) {
+ rcc_turn_off_clk(w_board_pll_in_clk);
+ }
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))
+ // Enable the PLL input clock, and wait until it's ready.
+ rcc_turn_on_clk(w_board_pll_in_clk);
+ while (!rcc_is_clk_ready(w_board_pll_in_clk))
;
// Configure AHBx, APBx, etc. prescalers and the main PLL.
@@ -139,42 +170,12 @@ static void setup_clocks(void) {
rcc_switch_sysclk(RCC_CLKSRC_PLL);
}
-/*
- * These addresses are where usercode starts when a bootloader is
- * present. If no bootloader is present, the user NVIC usually starts
- * at the Flash base address, 0x08000000.
- */
-#if defined(BOOTLOADER_maple)
-#define USER_ADDR_ROM 0x08005000
-#elif defined(BOOTLOADER_robotis)
-#define USER_ADDR_ROM 0x08003000
-#endif
-#define USER_ADDR_RAM 0x20000C00
-extern char __text_start__;
-
-static void setup_nvic(void) {
-#ifdef VECT_TAB_FLASH
- nvic_init(USER_ADDR_ROM, 0);
-#elif defined VECT_TAB_RAM
- nvic_init(USER_ADDR_RAM, 0);
-#elif defined VECT_TAB_BASE
- nvic_init((uint32)0x08000000, 0);
-#elif defined VECT_TAB_ADDR
- // A numerically supplied value
- nvic_init((uint32)VECT_TAB_ADDR, 0);
-#else
- // Use the __text_start__ value from the linker script; this
- // should be the start of the vector table.
- nvic_init((uint32)&__text_start__, 0);
-#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) {
+__weak void board_setup_adcs(void) {
adc_set_prescaler(wirish::priv::w_adc_pre);
adc_foreach(adc_default_config);
}
@@ -214,6 +215,9 @@ static void timer_default_config(timer_dev *dev) {
timer_resume(dev);
}
-static void setup_timers(void) {
+__weak void board_setup_timers(void) {
timer_foreach(timer_default_config);
}
+
+}
+}
diff --git a/wirish/boards/cm900/board.cpp b/wirish/boards/robotis_cm900/board.cpp
index ec747b3..735bf33 100644
--- a/wirish/boards/cm900/board.cpp
+++ b/wirish/boards/robotis_cm900/board.cpp
@@ -1,5 +1,5 @@
/*
- * cm900.cpp
+ * robotis_cm900.cpp
*
* Created on: 2012. 10. 14.
* Author: in2storm
@@ -31,12 +31,6 @@
* SOFTWARE.
*****************************************************************************/
-/**
- * @file maple.cpp
- * @author Marti Bolivar <mbolivar@leaflabs.com>
- * @brief Maple PIN_MAP and boardInit().
- */
-
#include <board/board.h> // For this board's header file
#include <wirish/wirish_types.h> // For stm32_pin_info and its contents
diff --git a/wirish/boards/cm900/include/board/board.h b/wirish/boards/robotis_cm900/include/board/board.h
index fed1a1b..7eab980 100644
--- a/wirish/boards/cm900/include/board/board.h
+++ b/wirish/boards/robotis_cm900/include/board/board.h
@@ -27,7 +27,7 @@
/*
- * CM900.h
+ * robotis_cm900.h
*
* Created on: 2012. 10. 14.
* Author: ROBOTIS[sm6787@robotis.com]
diff --git a/wirish/boards/opencm904/board.cpp b/wirish/boards/robotis_opencm904/board.cpp
index b3c600b..19220fb 100644
--- a/wirish/boards/opencm904/board.cpp
+++ b/wirish/boards/robotis_opencm904/board.cpp
@@ -24,11 +24,6 @@
* SOFTWARE.
*****************************************************************************/
-/**
- * @file maple.cpp
- * @author Marti Bolivar <mbolivar@leaflabs.com>
- * @brief Maple PIN_MAP and boardInit().
- */
/*
* CM904.cpp ported from CM900.cpp
*
diff --git a/wirish/boards/opencm904/include/board/board.h b/wirish/boards/robotis_opencm904/include/board/board.h
index 274a2a7..274a2a7 100644
--- a/wirish/boards/opencm904/include/board/board.h
+++ b/wirish/boards/robotis_opencm904/include/board/board.h
diff --git a/wirish/boards/nucleo/board.cpp b/wirish/boards/st_nucleo_f103rb/board.cpp
index 641f542..ea2f5c6 100644
--- a/wirish/boards/nucleo/board.cpp
+++ b/wirish/boards/st_nucleo_f103rb/board.cpp
@@ -25,9 +25,9 @@
*****************************************************************************/
/**
- * @file wirish/boards/nucleo/board.cpp
+ * @file wirish/boards/st_nucleo_f103rb/board.cpp
* @author Grégoire Passault <g.passault@gmail.com>
- * @brief Nucleo board file
+ * @brief st_nucleo_f103rb board file
*
* This mapping was done using the NUCLEO documentation and may be incomplete
* or contains error
diff --git a/wirish/boards/nucleo/include/board/board.h b/wirish/boards/st_nucleo_f103rb/include/board/board.h
index f7e3a38..7788cd8 100644
--- a/wirish/boards/nucleo/include/board/board.h
+++ b/wirish/boards/st_nucleo_f103rb/include/board/board.h
@@ -25,9 +25,9 @@
*****************************************************************************/
/**
- * @file wirish/boards/maple/include/board/board.h
- * @author Marti Bolivar <mbolivar@leaflabs.com>
- * @brief Maple board header.
+ * @file wirish/boards/st_nucleo_f103rb/include/board/board.h
+ * @author Grégoire Passault <g.passault@gmail.com>
+ * @brief st_nucleo_f103rb board header.
*/
#ifndef _BOARD_MAPLE_H_
diff --git a/wirish/boards/st_stm32f401cdiscovery/board.cpp b/wirish/boards/st_stm32f401cdiscovery/board.cpp
new file mode 100644
index 0000000..7f89ab6
--- /dev/null
+++ b/wirish/boards/st_stm32f401cdiscovery/board.cpp
@@ -0,0 +1,177 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2011 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/maple/board.cpp
+ * @author Perry Huang <iperry@leaflabs.com>, Bryan Newbold <bnewbold@robocracy.org
+ * @brief STM32F401C Discovery board file.
+ */
+
+#include <board/board.h> // For this board's header file
+
+#include <wirish/wirish_types.h> // For stm32_pin_info and its contents
+ // (these go into PIN_MAP).
+
+#include "boards_private.h" // For PMAP_ROW(), which makes
+ // PIN_MAP easier to read.
+
+// boardInit(): nothing special to do for Maple.
+//
+// When defining your own board.cpp, you can put extra code in this
+// function if you have anything you want done on reset, before main()
+// or setup() are called.
+//
+// If there's nothing special you need done, feel free to leave this
+// function out.
+void boardInit(void) {
+ // Disable on-board MEMS Gycroscope by pulling PE3 high (nCS line).
+ // If this isn't done, use of SPI peripheral 1 will fail mysteriously due
+ // to the Gyro writing to MISO.
+ // To re-enable and use the gyro, pull PE3 (D67) low in setup().
+ gpio_set_mode(GPIOE, 3, GPIO_MODE_OUTPUT);
+ gpio_write_bit(GPIOE, 3, 1);
+}
+
+// Pin map: this lets the basic I/O functions (digitalWrite(),
+// analogRead(), pwmWrite()) translate from pin numbers to STM32
+// peripherals.
+//
+// PMAP_ROW() lets us specify a row (really a struct stm32_pin_info)
+// in the pin map. Its arguments are:
+//
+// - GPIO device for the pin (GPIOA, etc.)
+// - GPIO bit for the pin (0 through 15)
+// - Timer device, or NULL if none
+// - Timer channel (1 to 4, for PWM), or 0 if none
+// - ADC device, or NULL if none
+// - ADC channel, or ADCx if none
+//
+// TODO: This table is definately not complete for the STM32F401C!!
+extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = {
+ PMAP_ROW(GPIOA, 0, NULL, 0, NULL, ADCx), /* D0/PA0 */
+ PMAP_ROW(GPIOA, 1, NULL, 0, NULL, ADCx), /* D1/PA1 */
+ PMAP_ROW(GPIOA, 2, NULL, 0, NULL, ADCx), /* D2/PA2 */
+ PMAP_ROW(GPIOA, 3, NULL, 0, NULL, ADCx), /* D3/PA3 */
+ PMAP_ROW(GPIOA, 4, NULL, 0, NULL, ADCx), /* D4/PA4 */
+ PMAP_ROW(GPIOA, 5, NULL, 0, NULL, ADCx), /* D5/PA5 */
+ PMAP_ROW(GPIOA, 6, NULL, 0, NULL, ADCx), /* D6/PA6 */
+ PMAP_ROW(GPIOA, 7, NULL, 0, NULL, ADCx), /* D7/PA7 */
+ PMAP_ROW(GPIOA, 8, NULL, 0, NULL, ADCx), /* D8/PA8 */
+ PMAP_ROW(GPIOA, 9, NULL, 0, NULL, ADCx), /* D9/PA9 */
+ PMAP_ROW(GPIOA, 10, NULL, 0, NULL, ADCx), /* D10/PA10 */
+ PMAP_ROW(GPIOA, 11, NULL, 0, NULL, ADCx), /* D11/PA11 */
+ PMAP_ROW(GPIOA, 12, NULL, 0, NULL, ADCx), /* D12/PA12 */
+ PMAP_ROW(GPIOA, 13, NULL, 0, NULL, ADCx), /* D13/PA13 */
+ PMAP_ROW(GPIOA, 14, NULL, 0, NULL, ADCx), /* D14/PA14 */
+ PMAP_ROW(GPIOA, 15, NULL, 0, NULL, ADCx), /* D15/PA15 */
+
+ PMAP_ROW(GPIOB, 0, NULL, 0, NULL, ADCx), /* D16/PB0 */
+ PMAP_ROW(GPIOB, 1, NULL, 0, NULL, ADCx), /* D17/PB1 */
+ PMAP_ROW(GPIOB, 2, NULL, 0, NULL, ADCx), /* D18/PB2 */
+ PMAP_ROW(GPIOB, 3, NULL, 0, NULL, ADCx), /* D19/PB3 */
+ PMAP_ROW(GPIOB, 4, NULL, 0, NULL, ADCx), /* D20/PB4 */
+ PMAP_ROW(GPIOB, 5, NULL, 0, NULL, ADCx), /* D21/PB5 */
+ PMAP_ROW(GPIOB, 6, NULL, 0, NULL, ADCx), /* D22/PB6 */
+ PMAP_ROW(GPIOB, 7, NULL, 0, NULL, ADCx), /* D23/PB7 */
+ PMAP_ROW(GPIOB, 8, NULL, 0, NULL, ADCx), /* D24/PB8 */
+ PMAP_ROW(GPIOB, 9, NULL, 0, NULL, ADCx), /* D25/PB9 */
+ PMAP_ROW(GPIOB, 10, NULL, 0, NULL, ADCx), /* D26/PB10 */
+ PMAP_ROW(GPIOB, 11, NULL, 0, NULL, ADCx), /* D27/PB11 */
+ PMAP_ROW(GPIOB, 12, NULL, 0, NULL, ADCx), /* D28/PB12 */
+ PMAP_ROW(GPIOB, 13, NULL, 0, NULL, ADCx), /* D29/PB13 */
+ PMAP_ROW(GPIOB, 14, NULL, 0, NULL, ADCx), /* D30/PB14 */
+ PMAP_ROW(GPIOB, 15, NULL, 0, NULL, ADCx), /* D31/PB15 */
+
+ PMAP_ROW(GPIOC, 0, NULL, 0, NULL, ADCx), /* D32/PC0 */
+ PMAP_ROW(GPIOC, 1, NULL, 0, NULL, ADCx), /* D33/PC1 */
+ PMAP_ROW(GPIOC, 2, NULL, 0, NULL, ADCx), /* D34/PC2 */
+ PMAP_ROW(GPIOC, 3, NULL, 0, NULL, ADCx), /* D35/PC3 */
+ PMAP_ROW(GPIOC, 4, NULL, 0, NULL, ADCx), /* D36/PC4 */
+ PMAP_ROW(GPIOC, 5, NULL, 0, NULL, ADCx), /* D37/PC5 */
+ PMAP_ROW(GPIOC, 6, NULL, 0, NULL, ADCx), /* D38/PC6 */
+ PMAP_ROW(GPIOC, 7, NULL, 0, NULL, ADCx), /* D39/PC7 */
+ PMAP_ROW(GPIOC, 8, NULL, 0, NULL, ADCx), /* D40/PC8 */
+ PMAP_ROW(GPIOC, 9, NULL, 0, NULL, ADCx), /* D41/PC9 */
+ PMAP_ROW(GPIOC, 10, NULL, 0, NULL, ADCx), /* D42/PC10 */
+ PMAP_ROW(GPIOC, 11, NULL, 0, NULL, ADCx), /* D43/PC11 */
+ PMAP_ROW(GPIOC, 12, NULL, 0, NULL, ADCx), /* D44/PC12 */
+ PMAP_ROW(GPIOC, 13, NULL, 0, NULL, ADCx), /* D45/PC13 */
+ PMAP_ROW(GPIOC, 14, NULL, 0, NULL, ADCx), /* D46/PC14 */
+ PMAP_ROW(GPIOC, 15, NULL, 0, NULL, ADCx), /* D47/PC15 */
+
+ PMAP_ROW(GPIOD, 0, NULL, 0, NULL, ADCx), /* D48/PD0 */
+ PMAP_ROW(GPIOD, 1, NULL, 0, NULL, ADCx), /* D49/PD1 */
+ PMAP_ROW(GPIOD, 2, NULL, 0, NULL, ADCx), /* D50/PD2 */
+ PMAP_ROW(GPIOD, 3, NULL, 0, NULL, ADCx), /* D51/PD3 */
+ PMAP_ROW(GPIOD, 4, NULL, 0, NULL, ADCx), /* D52/PD4 */
+ PMAP_ROW(GPIOD, 5, NULL, 0, NULL, ADCx), /* D53/PD5 */
+ PMAP_ROW(GPIOD, 6, NULL, 0, NULL, ADCx), /* D54/PD6 */
+ PMAP_ROW(GPIOD, 7, NULL, 0, NULL, ADCx), /* D55/PD7 */
+ PMAP_ROW(GPIOD, 8, NULL, 0, NULL, ADCx), /* D56/PD8 */
+ PMAP_ROW(GPIOD, 9, NULL, 0, NULL, ADCx), /* D57/PD9 */
+ PMAP_ROW(GPIOD, 10, NULL, 0, NULL, ADCx), /* D58/PD10 */
+ PMAP_ROW(GPIOD, 11, NULL, 0, NULL, ADCx), /* D59/PD11 */
+ PMAP_ROW(GPIOD, 12, NULL, 0, NULL, ADCx), /* D60/PD12 */
+ PMAP_ROW(GPIOD, 13, NULL, 0, NULL, ADCx), /* D61/PD13 */
+ PMAP_ROW(GPIOD, 14, NULL, 0, NULL, ADCx), /* D62/PD14 */
+ PMAP_ROW(GPIOD, 15, NULL, 0, NULL, ADCx), /* D63/PD15 */
+
+ PMAP_ROW(GPIOE, 0, NULL, 0, NULL, ADCx), /* D64/PE0 */
+ PMAP_ROW(GPIOE, 1, NULL, 0, NULL, ADCx), /* D65/PE1 */
+ PMAP_ROW(GPIOE, 2, NULL, 0, NULL, ADCx), /* D66/PE2 */
+ PMAP_ROW(GPIOE, 3, NULL, 0, NULL, ADCx), /* D67/PE3 */
+ PMAP_ROW(GPIOE, 4, NULL, 0, NULL, ADCx), /* D68/PE4 */
+ PMAP_ROW(GPIOE, 5, NULL, 0, NULL, ADCx), /* D69/PE5 */
+ PMAP_ROW(GPIOE, 6, NULL, 0, NULL, ADCx), /* D70/PE6 */
+ PMAP_ROW(GPIOE, 7, NULL, 0, NULL, ADCx), /* D71/PE7 */
+ PMAP_ROW(GPIOE, 8, NULL, 0, NULL, ADCx), /* D72/PE8 */
+ PMAP_ROW(GPIOE, 9, NULL, 0, NULL, ADCx), /* D73/PE9 */
+ PMAP_ROW(GPIOE, 10, NULL, 0, NULL, ADCx), /* D74/PE10 */
+ PMAP_ROW(GPIOE, 11, NULL, 0, NULL, ADCx), /* D75/PE11 */
+ PMAP_ROW(GPIOE, 12, NULL, 0, NULL, ADCx), /* D76/PE12 */
+ PMAP_ROW(GPIOE, 13, NULL, 0, NULL, ADCx), /* D77/PE13 */
+ PMAP_ROW(GPIOE, 14, NULL, 0, NULL, ADCx), /* D78/PE14 */
+ PMAP_ROW(GPIOE, 15, NULL, 0, NULL, ADCx), /* D79/PE15 */
+};
+
+// Array of pins you can use for pwmWrite(). Keep it in Flash because
+// it doesn't change, and so we don't waste RAM.
+extern const uint8 boardPWMPins[] __FLASH__ = {
+ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 27, 28
+};
+
+// Array of pins you can use for analogRead().
+extern const uint8 boardADCPins[] __FLASH__ = {
+ 0,
+};
+
+// Array of pins that the board uses for something special. Other than
+// the button and the LED, it's usually best to leave these pins alone
+// unless you know what you're doing.
+extern const uint8 boardUsedPins[] __FLASH__ = {
+ BOARD_LED_PIN, BOARD_BUTTON_PIN, BOARD_JTMS_SWDIO_PIN,
+ BOARD_JTCK_SWCLK_PIN, BOARD_JTDI_PIN, BOARD_JTDO_PIN, BOARD_NJTRST_PIN
+};
diff --git a/wirish/boards/st_stm32f401cdiscovery/include/board/board.h b/wirish/boards/st_stm32f401cdiscovery/include/board/board.h
new file mode 100644
index 0000000..d93bc30
--- /dev/null
+++ b/wirish/boards/st_stm32f401cdiscovery/include/board/board.h
@@ -0,0 +1,127 @@
+/******************************************************************************
+ * The MIT License
+ *
+ * Copyright (c) 2011 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/maple/include/board/board.h
+ * @author Perry Huang <iperry@leaflabs.com>, Bryan Newbold <bnewbold@robocracy.org
+ * @brief STM32F401C Discovery board file.
+ */
+
+#ifndef _BOARD_STM32F401_DISCOVERY_H_
+#define _BOARD_STM32F401_DISCOVERY_H_
+
+/* 84 MHz -> 84 cycles per microsecond. */
+#define CYCLES_PER_MICROSECOND 84
+
+// PLL config for 8 MHz external crystal
+// --> 84 MHz SYSCLK, with 48 MHz PLL48CK.
+//
+// Additional constraints:
+// ASSERT_FAULT((data->pllq >= 4) && (data->pllq <= 15));
+// ASSERT_FAULT((data->pllp >= 2) && (data->pllp <= 8));
+// ASSERT_FAULT(!(data->pllp & 1));
+// ASSERT_FAULT((data->plln >= 192) && (data->plln <= 432));
+// ASSERT_FAULT((data->pllm >= 2) && (data->pllm <= 63));
+//
+// f_VCO = (INPUT) X (PLL_N / PLL_M)
+#define BOARD_PLL_N 336
+#define BOARD_PLL_M 8
+// SYSCLK = f_PLL = f_VCO / PLL_P; PLL_P = {2, 4, 6, 8}
+#define BOARD_PLL_P 4
+// PLL48CK = f_USBETC = f_VCO / PLL_Q; 2 <= PLL_Q <= 15
+#define BOARD_PLL_Q 7 // should be 2?
+
+/* Pin number for the built-in button (USER button on STM32F401DISCOVERY) */
+#define BOARD_BUTTON_PIN PA0
+
+/* Pin number for the built-in LED (blue LED on STM32F401DISCOVERY) */
+#define BOARD_LED_PIN PD15
+
+/* Number of USARTs/UARTs whose pins are broken out to headers. */
+#define BOARD_NR_USARTS 3
+
+/* USART pin numbers. */
+#define BOARD_USART1_TX_PIN PA9
+#define BOARD_USART1_RX_PIN PA10
+#define BOARD_USART2_TX_PIN PA2
+#define BOARD_USART2_RX_PIN PA3
+#define BOARD_USART3_TX_PIN PB10
+#define BOARD_USART3_RX_PIN PB11
+
+/* Number of SPI ports broken out to headers. */
+#define BOARD_NR_SPI 2
+
+/* SPI pin numbers. */
+#define BOARD_SPI1_NSS_PIN PA4
+#define BOARD_SPI1_MOSI_PIN PA7
+#define BOARD_SPI1_MISO_PIN PA6
+#define BOARD_SPI1_SCK_PIN PA5
+
+#define BOARD_SPI2_NSS_PIN 28
+#define BOARD_SPI2_MOSI_PIN 31
+#define BOARD_SPI2_MISO_PIN 30
+#define BOARD_SPI2_SCK_PIN 29
+
+/* Total number of GPIO pins that are broken out to headers and
+ * intended for use. This includes pins like the LED, button, and
+ * debug port (JTAG/SWD) pins. */
+#define BOARD_NR_GPIO_PINS 80
+
+/* Number of pins capable of PWM output. */
+#define BOARD_NR_PWM_PINS 5
+
+/* Number of pins capable of ADC conversion. */
+#define BOARD_NR_ADC_PINS 1
+
+/* Number of pins already connected to external hardware. For Maple,
+ * these are just BOARD_LED_PIN, BOARD_BUTTON_PIN, and the debug port
+ * pins (see below). */
+#define BOARD_NR_USED_PINS 7
+
+/* Debug port pins. */
+#define BOARD_JTMS_SWDIO_PIN 39
+#define BOARD_JTCK_SWCLK_PIN 40
+#define BOARD_JTDI_PIN 41
+#define BOARD_JTDO_PIN 42
+#define BOARD_NJTRST_PIN 43
+
+/* USB configuration. BOARD_USB_DISC_DEV is the GPIO port containing
+ * the USB_DISC pin, and BOARD_USB_DISC_BIT is that pin's bit. */
+#define BOARD_USB_DISC_DEV GPIOC
+#define BOARD_USB_DISC_BIT 12
+
+/* Pin aliases: these give the GPIO port/bit for each pin as an
+ * enum. These are optional, but recommended. They make it easier to
+ * write code using low-level GPIO functionality. */
+enum {
+ PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15,
+ PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15,
+ PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9, PC10, PC11, PC12, PC13, PC14, PC15,
+ PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9, PD10, PD11, PD12, PD13, PD14, PD15,
+ PE0, PE1, PE2, PE3, PE4, PE5, PE6, PE7, PE8, PE9, PE10, PE11, PE12, PE13, PE14, PE15,
+};
+
+#endif
diff --git a/wirish/boards/VLDiscovery/board.cpp b/wirish/boards/st_stm32vldiscovery/board.cpp
index c86204d..a787472 100644
--- a/wirish/boards/VLDiscovery/board.cpp
+++ b/wirish/boards/st_stm32vldiscovery/board.cpp
@@ -25,9 +25,9 @@
*****************************************************************************/
/**
- * @file wirish/boards/VLDiscovery/board.cpp
+ * @file wirish/boards/st_stm32vldiscovery/board.cpp
* @author Anton Eltchaninov <anton.eltchaninov@gmail.com>
- * @brief VLDiscovery board file.
+ * @brief st_stm32vldiscovery board file.
*/
#include <board/board.h>
diff --git a/wirish/boards/VLDiscovery/include/board/board.h b/wirish/boards/st_stm32vldiscovery/include/board/board.h
index 04d21c7..e976add 100644
--- a/wirish/boards/VLDiscovery/include/board/board.h
+++ b/wirish/boards/st_stm32vldiscovery/include/board/board.h
@@ -25,9 +25,9 @@
*****************************************************************************/
/**
- * @file wirish/boards/VLDiscovery/include/board/board.h
+ * @file wirish/boards/st_stm32vldiscovery/include/board/board.h
* @author Anton Eltchaninov <anton.eltchaninov@gmail.com>
- * @brief VLDiscovery board header.
+ * @brief st_stm32vldiscovery board header.
*/
#ifndef _BOARD_VLDISCOVERY_H_
diff --git a/wirish/boards_private.h b/wirish/boards_private.h
index 49867ca..642a9ee 100644
--- a/wirish/boards_private.h
+++ b/wirish/boards_private.h
@@ -48,21 +48,30 @@ namespace wirish {
namespace priv {
/*
- * Chip-specific initialization data
+ * Chip- and board-specific initialization data
*/
extern rcc_pll_cfg w_board_pll_cfg;
+ extern rcc_clk w_board_pll_in_clk;
extern adc_prescaler w_adc_pre;
extern adc_smp_rate w_adc_smp;
/*
- * Chip-specific initialization routines and helper functions.
+ * Chip- and board-specific initialization routines and helper
+ * functions.
+ *
+ * Some of these have default (weak) implementations in
+ * boards.cpp; define them in your board file to override.
*/
void board_reset_pll(void);
void board_setup_clock_prescalers(void);
void board_setup_gpio(void);
void board_setup_usb(void);
+ void board_setup_flash(void);
+ void board_setup_adcs(void);
+ void board_setup_timers(void);
+ void board_setup_clocks(void);
void series_init(void);
}
diff --git a/wirish/include/wirish/ext_interrupts.h b/wirish/include/wirish/ext_interrupts.h
index ce1ca03..7b82c40 100644
--- a/wirish/include/wirish/ext_interrupts.h
+++ b/wirish/include/wirish/ext_interrupts.h
@@ -106,7 +106,7 @@ void detachInterrupt(uint8 pin);
*
* @see noInterrupts()
*/
-static __always_inline void interrupts() {
+static inline void interrupts() {
nvic_globalirq_enable();
}
@@ -120,7 +120,7 @@ static __always_inline void interrupts() {
*
* @see interrupts()
*/
-static __always_inline void noInterrupts() {
+static inline void noInterrupts() {
nvic_globalirq_disable();
}
diff --git a/wirish/include/wirish/wirish.h b/wirish/include/wirish/wirish.h
index 610aa3f..606aac0 100644
--- a/wirish/include/wirish/wirish.h
+++ b/wirish/include/wirish/wirish.h
@@ -58,8 +58,13 @@
/* Wiring macros and bit defines */
-#define true 0x1
-#define false 0x0
+// These may have been defined if stdbool.h was included
+#ifndef true
+# define true 0x1
+#endif
+#ifndef false
+# define false 0x0
+#endif
#define LSBFIRST 0
#define MSBFIRST 1
diff --git a/wirish/include/wirish/wirish_math.h b/wirish/include/wirish/wirish_math.h
index 39f16a0..ff264dc 100644
--- a/wirish/include/wirish/wirish_math.h
+++ b/wirish/include/wirish/wirish_math.h
@@ -93,7 +93,8 @@ static inline long map(long value, long fromStart, long fromEnd,
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
-#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
+#define round(x) ((x)>=0?(long)((x)+(double)0.5):(long)((x)-(double)0.5))
+#define roundf(x) ((x)>=0?(long)((x)+(float)0.5):(long)((x)-(float)0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
diff --git a/wirish/rules.mk b/wirish/rules.mk
index 1cac74a..13da229 100644
--- a/wirish/rules.mk
+++ b/wirish/rules.mk
@@ -4,15 +4,25 @@ dirstack_$(sp) := $(d)
d := $(dir)
BUILDDIRS += $(BUILD_PATH)/$(d)
-# Add board directory and MCU-specific directory to BUILDDIRS. These
-# are in subdirectories, but they're logically part of the Wirish
-# submodule.
+# Add board directory and target-specific directory to
+# BUILDDIRS. These are in subdirectories, but they're logically part
+# of the Wirish submodule. That's a bit inconsistent with libmaple
+# proper, and should be fixed.
+# Optionally support out-of-tree board files if WIRISH_BOARD_PATH was exported
+ifeq ($(WIRISH_BOARD_PATH),)
WIRISH_BOARD_PATH := boards/$(BOARD)
+WIRISH_BOARD_INCLUDE := $(d)/$(WIRISH_BOARD_PATH)/include
+WIRISH_BOARD_CPP_FILE := $(d)/$(WIRISH_BOARD_PATH)/board.cpp
BUILDDIRS += $(BUILD_PATH)/$(d)/$(WIRISH_BOARD_PATH)
-BUILDDIRS += $(BUILD_PATH)/$(d)/$(MCU_SERIES)
+else
+WIRISH_BOARD_INCLUDE := $(WIRISH_BOARD_PATH)/include
+WIRISH_BOARD_CPP_FILE := $(WIRISH_BOARD_PATH)/board.cpp
+BUILDDIRS += $(BUILD_PATH)/$(WIRISH_BOARD_PATH)
+endif
+BUILDDIRS += $(BUILD_PATH)/$(d)/$(TARGET_SERIES_MODULE)
# Safe includes for Wirish.
-WIRISH_INCLUDES := -I$(d)/include -I$(d)/$(WIRISH_BOARD_PATH)/include
+WIRISH_INCLUDES := -I$(d)/include -I$(WIRISH_BOARD_INCLUDE)
# Local flags. Add -I$(d) to allow for private includes.
CFLAGS_$(d) := $(LIBMAPLE_INCLUDES) $(WIRISH_INCLUDES) -I$(d)
@@ -21,7 +31,7 @@ CFLAGS_$(d) := $(LIBMAPLE_INCLUDES) $(WIRISH_INCLUDES) -I$(d)
sSRCS_$(d) := start.S
cSRCS_$(d) := start_c.c
cSRCS_$(d) += syscalls.c
-cSRCS_$(d) += $(MCU_SERIES)/util_hooks.c
+cSRCS_$(d) += $(TARGET_SERIES_MODULE)/util_hooks.c
cppSRCS_$(d) := boards.cpp
cppSRCS_$(d) += cxxabi-compat.cpp
cppSRCS_$(d) += ext_interrupts.cpp
@@ -38,15 +48,18 @@ cppSRCS_$(d) += wirish_digital.cpp
cppSRCS_$(d) += wirish_math.cpp
cppSRCS_$(d) += wirish_shift.cpp
cppSRCS_$(d) += wirish_time.cpp
-cppSRCS_$(d) += $(MCU_SERIES)/boards_setup.cpp
-cppSRCS_$(d) += $(MCU_SERIES)/wirish_digital.cpp
-cppSRCS_$(d) += $(MCU_SERIES)/wirish_debug.cpp
-cppSRCS_$(d) += $(WIRISH_BOARD_PATH)/board.cpp
+cppSRCS_$(d) += $(TARGET_SERIES_MODULE)/boards_setup.cpp
+cppSRCS_$(d) += $(TARGET_SERIES_MODULE)/wirish_digital.cpp
+cppSRCS_$(d) += $(TARGET_SERIES_MODULE)/wirish_debug.cpp
sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%)
cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%)
cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%)
+# board.cpp is a special case, because it may be out of tree
+cppSRCS_$(d) += $(WIRISH_BOARD_PATH)/board.cpp
+cppFILES_$(d) += $(WIRISH_BOARD_CPP_FILE)
+
OBJS_$(d) := $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) \
$(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) \
$(cppFILES_$(d):%.cpp=$(BUILD_PATH)/%.o)
diff --git a/wirish/stm32f2/boards_setup.cpp b/wirish/stm32f2-f4/boards_setup.cpp
index 5764dd0..aa44a11 100644
--- a/wirish/stm32f2/boards_setup.cpp
+++ b/wirish/stm32f2-f4/boards_setup.cpp
@@ -42,19 +42,43 @@
#include <wirish/wirish_types.h>
#include <board/board.h>
-// PLL config for 25 MHz external crystal --> 120 MHz SYSCLK, with
-// 48 MHz PLL48CK.
-#ifndef BOARD_PLL_Q
-#define BOARD_PLL_Q 5
-#endif
-#ifndef BOARD_PLL_P
-#define BOARD_PLL_P 2
-#endif
-#ifndef BOARD_PLL_N
-#define BOARD_PLL_N 240
-#endif
-#ifndef BOARD_PLL_M
-#define BOARD_PLL_M 25
+// Not used by STM32F2
+#define FPU_CPACR 0xE000ED88
+
+/* See libmaple/stm32f2-f4/rcc.c for constraints on these values, or the vendor
+ * user manual */
+#if STM32_MCU_SERIES == STM32_SERIES_F2
+ // PLL config for 25 MHz external crystal --> 120 MHz SYSCLK, with
+ // 48 MHz PLL48CK.
+# ifndef BOARD_PLL_Q
+# define BOARD_PLL_Q 5
+# endif
+# ifndef BOARD_PLL_P
+# define BOARD_PLL_P 2
+# endif
+# ifndef BOARD_PLL_N
+# define BOARD_PLL_N 240
+# endif
+# ifndef BOARD_PLL_M
+# define BOARD_PLL_M 25
+# endif
+#elif STM32_MCU_SERIES == STM32_SERIES_F4
+ // PLL config for 8 MHz external crystal --> 84 MHz SYSCLK, with
+ // 48 MHz PLL48CK.
+# ifndef BOARD_PLL_Q
+# define BOARD_PLL_Q 7
+# endif
+# ifndef BOARD_PLL_P
+# define BOARD_PLL_P 4
+# endif
+# ifndef BOARD_PLL_N
+# define BOARD_PLL_N 336
+# endif
+# ifndef BOARD_PLL_M
+# define BOARD_PLL_M 8
+# endif
+#else
+# error "Unsupported STM32_MCU_SERIES"
#endif
static stm32f2_rcc_pll_data pll_data = {BOARD_PLL_Q,
@@ -89,6 +113,7 @@ namespace wirish {
}
__weak void board_setup_clock_prescalers(void) {
+#if STM32_MCU_SERIES == STM32_SERIES_F2
// On F2, with f_SYSCLK = 120 MHz (as determined by
// board_pll_cfg),
//
@@ -98,6 +123,19 @@ namespace wirish {
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);
+#elif STM32_MCU_SERIES == STM32_SERIES_F4
+ // On F2, with f_SYSCLK = 84 MHz (as determined by
+ // board_pll_cfg),
+ //
+ // f_AHB = f_SYSCLK / 1 = 84 MHz
+ // f_APB1 = f_AHB / 2 = 42 MHz
+ // f_APB2 = f_AHB / 1 = 84 MHz
+ 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);
+#else
+# error "Unsupported STM32_MCU_SERIES"
+#endif
}
__weak void board_setup_gpio(void) {
@@ -114,6 +152,11 @@ namespace wirish {
// Turn on the I/O compensation cell, since we drive the
// GPIOs quickly by default.
syscfg_enable_io_compensation();
+
+#if STM32_MCU_SERIES == STM32_SERIES_F4
+ /* enable fpu with full access */
+ *(volatile unsigned int*)FPU_CPACR |= 0xF << 20;
+#endif
}
}
diff --git a/wirish/stm32f2/util_hooks.c b/wirish/stm32f2-f4/util_hooks.c
index 1b519ab..a18dfe8 100644
--- a/wirish/stm32f2/util_hooks.c
+++ b/wirish/stm32f2-f4/util_hooks.c
@@ -30,16 +30,50 @@
*/
#include <libmaple/nvic.h>
+#include <libmaple/gpio.h>
+#include <libmaple/stm32.h>
+#include <libmaple/timer.h>
+#include <libmaple/adc.h>
+#include <libmaple/usart.h>
+
+/* Failed ASSERT()s send out a message using this USART config. */
+#ifndef ERROR_USART
+#define ERROR_USART USART1
+#define ERROR_USART_BAUD 115200
+#define ERROR_TX_PORT GPIOA
+#define ERROR_TX_PIN 9
+#endif
/*
* Disables all peripheral interrupts. Called by __error() with global
* interrupts disabled.
*/
void __lm_error(void) {
+ /* Turn off peripheral interrupts */
nvic_irq_disable_all();
+
+ /* Turn off timers */
+ timer_disable_all();
+
+ /* Turn off ADC */
+ adc_disable_all();
+
+ /* Turn off all USARTs */
+ usart_disable_all();
+
+#if STM32_HAVE_USB
+ /* Turn the USB interrupt back on so the bootloader keeps on functioning */
+ nvic_irq_enable(NVIC_USB_HP_CAN_TX);
+ nvic_irq_enable(NVIC_USB_LP_CAN_RX0);
+#endif
}
/*
* Enable the error USART for writing.
*/
-/* usart_dev* __lm_enable_error_usart(void) { (TODO) } */
+usart_dev* __lm_enable_error_usart() {
+ // FIXME: gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_AF_OUTPUT_PP);
+ usart_init(ERROR_USART);
+ usart_set_baud_rate(ERROR_USART, USART_USE_PCLK, ERROR_USART_BAUD);
+ return ERROR_USART;
+}
diff --git a/wirish/stm32f2/wirish_debug.cpp b/wirish/stm32f2-f4/wirish_debug.cpp
index af6c78b..af6c78b 100644
--- a/wirish/stm32f2/wirish_debug.cpp
+++ b/wirish/stm32f2-f4/wirish_debug.cpp
diff --git a/wirish/stm32f2/wirish_digital.cpp b/wirish/stm32f2-f4/wirish_digital.cpp
index 4d46f1c..4d46f1c 100644
--- a/wirish/stm32f2/wirish_digital.cpp
+++ b/wirish/stm32f2-f4/wirish_digital.cpp