updated setup_nvic for maple mini, which seems to have been missed when I made the changed to do with removing VECT_TAB_FLASH

This commit is contained in:
Roger Clark 2015-05-06 03:09:15 +10:00
parent 13e27c1dc5
commit bb535029cb
1 changed files with 229 additions and 223 deletions

View File

@ -1,223 +1,229 @@
/****************************************************************************** /******************************************************************************
* The MIT License * The MIT License
* *
* Copyright (c) 2010 Perry Hung. * Copyright (c) 2010 Perry Hung.
* Copyright (c) 2011, 2012 LeafLabs, LLC. * Copyright (c) 2011, 2012 LeafLabs, LLC.
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without * files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, * restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies * modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is * of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be * The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software. * included in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*****************************************************************************/ *****************************************************************************/
/** /**
* @file wirish/boards.cpp * @file wirish/boards.cpp
* @brief init() and board routines. * @brief init() and board routines.
* *
* This file is mostly interesting for the init() function, which * This file is mostly interesting for the init() function, which
* configures Flash, the core clocks, and a variety of other available * configures Flash, the core clocks, and a variety of other available
* peripherals on the board so the rest of Wirish doesn't have to turn * peripherals on the board so the rest of Wirish doesn't have to turn
* things on before using them. * things on before using them.
* *
* Prior to returning, init() calls boardInit(), which allows boards * Prior to returning, init() calls boardInit(), which allows boards
* to perform any initialization they need to. This file includes a * to perform any initialization they need to. This file includes a
* weak no-op definition of boardInit(), so boards that don't need any * weak no-op definition of boardInit(), so boards that don't need any
* special initialization don't have to define their own. * special initialization don't have to define their own.
* *
* How init() works is chip-specific. See the boards_setup.cpp files * How init() works is chip-specific. See the boards_setup.cpp files
* under e.g. wirish/stm32f1/, wirish/stmf32f2 for the details, but be * under e.g. wirish/stm32f1/, wirish/stmf32f2 for the details, but be
* advised: their contents are unstable, and can/will change without * advised: their contents are unstable, and can/will change without
* notice. * notice.
*/ */
#include <boards.h> #include <boards.h>
#include <libmaple/libmaple_types.h> #include <libmaple/libmaple_types.h>
#include <libmaple/flash.h> #include <libmaple/flash.h>
#include <libmaple/nvic.h> #include <libmaple/nvic.h>
#include <libmaple/systick.h> #include <libmaple/systick.h>
#include "boards_private.h" #include "boards_private.h"
static void setup_flash(void); static void setup_flash(void);
static void setup_clocks(void); static void setup_clocks(void);
static void setup_nvic(void); static void setup_nvic(void);
static void setup_adcs(void); static void setup_adcs(void);
static void setup_timers(void); static void setup_timers(void);
/* /*
* Exported functions * Exported functions
*/ */
void init(void) { void init(void) {
setup_flash(); setup_flash();
setup_clocks(); setup_clocks();
setup_nvic(); setup_nvic();
systick_init(SYSTICK_RELOAD_VAL); systick_init(SYSTICK_RELOAD_VAL);
wirish::priv::board_setup_gpio(); wirish::priv::board_setup_gpio();
setup_adcs(); setup_adcs();
setup_timers(); setup_timers();
wirish::priv::board_setup_usb(); wirish::priv::board_setup_usb();
wirish::priv::series_init(); wirish::priv::series_init();
boardInit(); boardInit();
} }
/* Provide a default no-op boardInit(). */ /* Provide a default no-op boardInit(). */
__weak void boardInit(void) { __weak void boardInit(void) {
} }
/* You could farm this out to the files in boards/ if e.g. it takes /* You could farm this out to the files in boards/ if e.g. it takes
* too long to test on boards with lots of pins. */ * too long to test on boards with lots of pins. */
bool boardUsesPin(uint8 pin) { bool boardUsesPin(uint8 pin) {
for (int i = 0; i < BOARD_NR_USED_PINS; i++) { for (int i = 0; i < BOARD_NR_USED_PINS; i++) {
if (pin == boardUsedPins[i]) { if (pin == boardUsedPins[i]) {
return true; return true;
} }
} }
return false; return false;
} }
/* /*
* Auxiliary routines * Auxiliary routines
*/ */
static void setup_flash(void) { static void setup_flash(void) {
// Turn on as many Flash "go faster" features as // Turn on as many Flash "go faster" features as
// possible. flash_enable_features() just ignores any flags it // possible. flash_enable_features() just ignores any flags it
// can't support. // can't support.
flash_enable_features(FLASH_PREFETCH | FLASH_ICACHE | FLASH_DCACHE); flash_enable_features(FLASH_PREFETCH | FLASH_ICACHE | FLASH_DCACHE);
// Configure the wait states, assuming we're operating at "close // Configure the wait states, assuming we're operating at "close
// enough" to 3.3V. // enough" to 3.3V.
flash_set_latency(FLASH_SAFE_WAIT_STATES); flash_set_latency(FLASH_SAFE_WAIT_STATES);
} }
static void setup_clocks(void) { static void setup_clocks(void) {
// Turn on HSI. We'll switch to and run off of this while we're // Turn on HSI. We'll switch to and run off of this while we're
// setting up the main PLL. // setting up the main PLL.
rcc_turn_on_clk(RCC_CLK_HSI); rcc_turn_on_clk(RCC_CLK_HSI);
// Turn off and reset the clock subsystems we'll be using, as well // Turn off and reset the clock subsystems we'll be using, as well
// as the clock security subsystem (CSS). Note that resetting CFGR // as the clock security subsystem (CSS). Note that resetting CFGR
// to its default value of 0 implies a switch to HSI for SYSCLK. // to its default value of 0 implies a switch to HSI for SYSCLK.
RCC_BASE->CFGR = 0x00000000; RCC_BASE->CFGR = 0x00000000;
rcc_disable_css(); rcc_disable_css();
rcc_turn_off_clk(RCC_CLK_PLL); rcc_turn_off_clk(RCC_CLK_PLL);
rcc_turn_off_clk(RCC_CLK_HSE); rcc_turn_off_clk(RCC_CLK_HSE);
wirish::priv::board_reset_pll(); wirish::priv::board_reset_pll();
// Clear clock readiness interrupt flags and turn off clock // Clear clock readiness interrupt flags and turn off clock
// readiness interrupts. // readiness interrupts.
RCC_BASE->CIR = 0x00000000; RCC_BASE->CIR = 0x00000000;
// Enable HSE, and wait until it's ready. // Enable HSE, and wait until it's ready.
rcc_turn_on_clk(RCC_CLK_HSE); rcc_turn_on_clk(RCC_CLK_HSE);
while (!rcc_is_clk_ready(RCC_CLK_HSE)) while (!rcc_is_clk_ready(RCC_CLK_HSE))
; ;
// Configure AHBx, APBx, etc. prescalers and the main PLL. // Configure AHBx, APBx, etc. prescalers and the main PLL.
wirish::priv::board_setup_clock_prescalers(); wirish::priv::board_setup_clock_prescalers();
rcc_configure_pll(&wirish::priv::w_board_pll_cfg); rcc_configure_pll(&wirish::priv::w_board_pll_cfg);
// Enable the PLL, and wait until it's ready. // Enable the PLL, and wait until it's ready.
rcc_turn_on_clk(RCC_CLK_PLL); rcc_turn_on_clk(RCC_CLK_PLL);
while(!rcc_is_clk_ready(RCC_CLK_PLL)) while(!rcc_is_clk_ready(RCC_CLK_PLL))
; ;
// Finally, switch to the now-ready PLL as the main clock source. // Finally, switch to the now-ready PLL as the main clock source.
rcc_switch_sysclk(RCC_CLKSRC_PLL); rcc_switch_sysclk(RCC_CLKSRC_PLL);
} }
/* /*
* These addresses are where usercode starts when a bootloader is * These addresses are where usercode starts when a bootloader is
* present. If no bootloader is present, the user NVIC usually starts * present. If no bootloader is present, the user NVIC usually starts
* at the Flash base address, 0x08000000. * at the Flash base address, 0x08000000.
*/ */
#if defined(BOOTLOADER_maple) #if defined(BOOTLOADER_maple)
#define USER_ADDR_ROM 0x08005000 #define USER_ADDR_ROM 0x08005000
#else #else
#if defined(BOOTLOADER_robotis) #if defined(BOOTLOADER_robotis)
#define USER_ADDR_ROM 0x08003000 #define USER_ADDR_ROM 0x08003000
#else #else
#define USER_ADDR_ROM 0x08000000 #define USER_ADDR_ROM 0x08000000
#endif #endif
#endif #endif
#define USER_ADDR_RAM 0x20000C00 #define USER_ADDR_RAM 0x20000C00
extern char __text_start__; extern char __text_start__;
static void setup_nvic(void) { static void setup_nvic(void) {
#ifdef VECT_TAB_FLASH
nvic_init(USER_ADDR_ROM, 0); nvic_init((uint32)VECT_TAB_ADDR, 0);
#elif defined VECT_TAB_RAM
nvic_init(USER_ADDR_RAM, 0); /* Roger Clark. We now control nvic vector table in boards.txt using the build.vect paramater
#elif defined VECT_TAB_BASE #ifdef VECT_TAB_FLASH
nvic_init((uint32)0x08000000, 0); nvic_init(USER_ADDR_ROM, 0);
#elif defined VECT_TAB_ADDR #elif defined VECT_TAB_RAM
// A numerically supplied value nvic_init(USER_ADDR_RAM, 0);
nvic_init((uint32)VECT_TAB_ADDR, 0); #elif defined VECT_TAB_BASE
#else nvic_init((uint32)0x08000000, 0);
// Use the __text_start__ value from the linker script; this #elif defined VECT_TAB_ADDR
// should be the start of the vector table. // A numerically supplied value
nvic_init((uint32)&__text_start__, 0); nvic_init((uint32)VECT_TAB_ADDR, 0);
#endif #else
} // Use the __text_start__ value from the linker script; this
// should be the start of the vector table.
static void adc_default_config(const adc_dev *dev) { nvic_init((uint32)&__text_start__, 0);
adc_enable_single_swstart(dev); #endif
adc_set_sample_rate(dev, wirish::priv::w_adc_smp);
} */
}
static void setup_adcs(void) {
adc_set_prescaler(wirish::priv::w_adc_pre); static void adc_default_config(const adc_dev *dev) {
adc_foreach(adc_default_config); adc_enable_single_swstart(dev);
} adc_set_sample_rate(dev, wirish::priv::w_adc_smp);
}
static void timer_default_config(timer_dev *dev) {
timer_adv_reg_map *regs = (dev->regs).adv; static void setup_adcs(void) {
const uint16 full_overflow = 0xFFFF; adc_set_prescaler(wirish::priv::w_adc_pre);
const uint16 half_duty = 0x8FFF; adc_foreach(adc_default_config);
}
timer_init(dev);
timer_pause(dev); static void timer_default_config(timer_dev *dev) {
timer_adv_reg_map *regs = (dev->regs).adv;
regs->CR1 = TIMER_CR1_ARPE; const uint16 full_overflow = 0xFFFF;
regs->PSC = 1; const uint16 half_duty = 0x8FFF;
regs->SR = 0;
regs->DIER = 0; timer_init(dev);
regs->EGR = TIMER_EGR_UG; timer_pause(dev);
switch (dev->type) {
case TIMER_ADVANCED: regs->CR1 = TIMER_CR1_ARPE;
regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF; regs->PSC = 1;
// fall-through regs->SR = 0;
case TIMER_GENERAL: regs->DIER = 0;
timer_set_reload(dev, full_overflow); regs->EGR = TIMER_EGR_UG;
for (uint8 channel = 1; channel <= 4; channel++) { switch (dev->type) {
if (timer_has_cc_channel(dev, channel)) { case TIMER_ADVANCED:
timer_set_compare(dev, channel, half_duty); regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF;
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, // fall-through
TIMER_OC_PE); case TIMER_GENERAL:
} timer_set_reload(dev, full_overflow);
} for (uint8 channel = 1; channel <= 4; channel++) {
// fall-through if (timer_has_cc_channel(dev, channel)) {
case TIMER_BASIC: timer_set_compare(dev, channel, half_duty);
break; timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1,
} TIMER_OC_PE);
}
timer_generate_update(dev); }
timer_resume(dev); // fall-through
} case TIMER_BASIC:
break;
static void setup_timers(void) { }
timer_foreach(timer_default_config);
} timer_generate_update(dev);
timer_resume(dev);
}
static void setup_timers(void) {
timer_foreach(timer_default_config);
}