Made new generic STM32F103C board variant based on Maple mini. This is a work in process. It seems to work, but needs more tidying up ;-)
This commit is contained in:
parent
544908bb14
commit
6fec429e99
|
@ -253,7 +253,7 @@ GenericSTM32F103C.name= Generic STM32F103C
|
||||||
GenericSTM32F103C.upload.tool=upload_router
|
GenericSTM32F103C.upload.tool=upload_router
|
||||||
#GenericSTM32F103C.upload.tool=maple_upload
|
#GenericSTM32F103C.upload.tool=maple_upload
|
||||||
GenericSTM32F103C.build.core=maple
|
GenericSTM32F103C.build.core=maple
|
||||||
GenericSTM32F103C.build.variant=maple_mini
|
GenericSTM32F103C.build.variant=generic_stm32f103c
|
||||||
GenericSTM32F103C.upload.use_1200bps_touch=false
|
GenericSTM32F103C.upload.use_1200bps_touch=false
|
||||||
GenericSTM32F103C.upload.file_type=bin
|
GenericSTM32F103C.upload.file_type=bin
|
||||||
GenericSTM32F103C.upload.usbID=1EAF:0003
|
GenericSTM32F103C.upload.usbID=1EAF:0003
|
||||||
|
@ -261,16 +261,11 @@ GenericSTM32F103C.upload.auto_reset=true
|
||||||
GenericSTM32F103C.build.mcu=cortex-m3
|
GenericSTM32F103C.build.mcu=cortex-m3
|
||||||
GenericSTM32F103C.build.f_cpu=72000000L
|
GenericSTM32F103C.build.f_cpu=72000000L
|
||||||
GenericSTM32F103C.build.board=MAPLE_MINI_GENERIC
|
GenericSTM32F103C.build.board=MAPLE_MINI_GENERIC
|
||||||
GenericSTM32F103C.build.core=maple
|
|
||||||
GenericSTM32F103C.build.common_flags=-mthumb -march=armv7-m -D__STM32F1__
|
GenericSTM32F103C.build.common_flags=-mthumb -march=armv7-m -D__STM32F1__
|
||||||
GenericSTM32F103C.build.variant=maple_mini
|
|
||||||
GenericSTM32F103C.build.variant_system_lib=libmaple.a
|
GenericSTM32F103C.build.variant_system_lib=libmaple.a
|
||||||
GenericSTM32F103C.build.density=STM32_MEDIUM_DENSITY
|
GenericSTM32F103C.build.density=STM32_MEDIUM_DENSITY
|
||||||
GenericSTM32F103C.build.error_led_port=GPIOB
|
GenericSTM32F103C.build.error_led_port=GPIOB
|
||||||
GenericSTM32F103C.build.error_led_pin=1
|
GenericSTM32F103C.build.error_led_pin=1
|
||||||
GenericSTM32F103C.build.gcc_ver=gcc-arm-none-eabi-4.8.3-2014q1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ==UPLOAD MODE==
|
## ==UPLOAD MODE==
|
||||||
## F103CB USB to Flash upload
|
## F103CB USB to Flash upload
|
||||||
|
|
|
@ -1,412 +1,412 @@
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* The MIT License
|
* The MIT License
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011 LeafLabs, LLC.
|
* Copyright (c) 2011 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 libmaple/timer.c
|
* @file libmaple/timer.c
|
||||||
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||||
* @brief Portable timer routines.
|
* @brief Portable timer routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libmaple/timer.h>
|
#include <libmaple/timer.h>
|
||||||
#include <libmaple/stm32.h>
|
#include <libmaple/stm32.h>
|
||||||
#include "timer_private.h"
|
#include "timer_private.h"
|
||||||
|
|
||||||
static void disable_channel(timer_dev *dev, uint8 channel);
|
static void disable_channel(timer_dev *dev, uint8 channel);
|
||||||
static void pwm_mode(timer_dev *dev, uint8 channel);
|
static void pwm_mode(timer_dev *dev, uint8 channel);
|
||||||
static void output_compare_mode(timer_dev *dev, uint8 channel);
|
static void output_compare_mode(timer_dev *dev, uint8 channel);
|
||||||
|
|
||||||
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid);
|
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Devices
|
* Devices
|
||||||
*
|
*
|
||||||
* Defer to the timer_private API for declaring these.
|
* Defer to the timer_private API for declaring these.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if STM32_HAVE_TIMER(1)
|
#if STM32_HAVE_TIMER(1)
|
||||||
static timer_dev timer1 = ADVANCED_TIMER(1);
|
static timer_dev timer1 = ADVANCED_TIMER(1);
|
||||||
/** Timer 1 device (advanced) */
|
/** Timer 1 device (advanced) */
|
||||||
timer_dev *TIMER1 = &timer1;
|
timer_dev *TIMER1 = &timer1;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(2)
|
#if STM32_HAVE_TIMER(2)
|
||||||
static timer_dev timer2 = GENERAL_TIMER(2);
|
static timer_dev timer2 = GENERAL_TIMER(2);
|
||||||
/** Timer 2 device (general-purpose) */
|
/** Timer 2 device (general-purpose) */
|
||||||
timer_dev *TIMER2 = &timer2;
|
timer_dev *TIMER2 = &timer2;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(3)
|
#if STM32_HAVE_TIMER(3)
|
||||||
static timer_dev timer3 = GENERAL_TIMER(3);
|
static timer_dev timer3 = GENERAL_TIMER(3);
|
||||||
/** Timer 3 device (general-purpose) */
|
/** Timer 3 device (general-purpose) */
|
||||||
timer_dev *TIMER3 = &timer3;
|
timer_dev *TIMER3 = &timer3;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(4)
|
#if STM32_HAVE_TIMER(4)
|
||||||
static timer_dev timer4 = GENERAL_TIMER(4);
|
static timer_dev timer4 = GENERAL_TIMER(4);
|
||||||
/** Timer 4 device (general-purpose) */
|
/** Timer 4 device (general-purpose) */
|
||||||
timer_dev *TIMER4 = &timer4;
|
timer_dev *TIMER4 = &timer4;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(5)
|
#if STM32_HAVE_TIMER(5)
|
||||||
static timer_dev timer5 = GENERAL_TIMER(5);
|
static timer_dev timer5 = GENERAL_TIMER(5);
|
||||||
/** Timer 5 device (general-purpose) */
|
/** Timer 5 device (general-purpose) */
|
||||||
timer_dev *TIMER5 = &timer5;
|
timer_dev *TIMER5 = &timer5;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(6)
|
#if STM32_HAVE_TIMER(6)
|
||||||
static timer_dev timer6 = BASIC_TIMER(6);
|
static timer_dev timer6 = BASIC_TIMER(6);
|
||||||
/** Timer 6 device (basic) */
|
/** Timer 6 device (basic) */
|
||||||
timer_dev *TIMER6 = &timer6;
|
timer_dev *TIMER6 = &timer6;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(7)
|
#if STM32_HAVE_TIMER(7)
|
||||||
static timer_dev timer7 = BASIC_TIMER(7);
|
static timer_dev timer7 = BASIC_TIMER(7);
|
||||||
/** Timer 7 device (basic) */
|
/** Timer 7 device (basic) */
|
||||||
timer_dev *TIMER7 = &timer7;
|
timer_dev *TIMER7 = &timer7;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(8)
|
#if STM32_HAVE_TIMER(8)
|
||||||
static timer_dev timer8 = ADVANCED_TIMER(8);
|
static timer_dev timer8 = ADVANCED_TIMER(8);
|
||||||
/** Timer 8 device (advanced) */
|
/** Timer 8 device (advanced) */
|
||||||
timer_dev *TIMER8 = &timer8;
|
timer_dev *TIMER8 = &timer8;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(9)
|
#if STM32_HAVE_TIMER(9)
|
||||||
static timer_dev timer9 = RESTRICTED_GENERAL_TIMER(9, TIMER_DIER_TIE_BIT);
|
static timer_dev timer9 = RESTRICTED_GENERAL_TIMER(9, TIMER_DIER_TIE_BIT);
|
||||||
/** Timer 9 device (general-purpose) */
|
/** Timer 9 device (general-purpose) */
|
||||||
timer_dev *TIMER9 = &timer9;
|
timer_dev *TIMER9 = &timer9;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(10)
|
#if STM32_HAVE_TIMER(10)
|
||||||
static timer_dev timer10 = RESTRICTED_GENERAL_TIMER(10, TIMER_DIER_CC1IE_BIT);
|
static timer_dev timer10 = RESTRICTED_GENERAL_TIMER(10, TIMER_DIER_CC1IE_BIT);
|
||||||
/** Timer 10 device (general-purpose) */
|
/** Timer 10 device (general-purpose) */
|
||||||
timer_dev *TIMER10 = &timer10;
|
timer_dev *TIMER10 = &timer10;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(11)
|
#if STM32_HAVE_TIMER(11)
|
||||||
static timer_dev timer11 = RESTRICTED_GENERAL_TIMER(11, TIMER_DIER_CC1IE_BIT);
|
static timer_dev timer11 = RESTRICTED_GENERAL_TIMER(11, TIMER_DIER_CC1IE_BIT);
|
||||||
/** Timer 11 device (general-purpose) */
|
/** Timer 11 device (general-purpose) */
|
||||||
timer_dev *TIMER11 = &timer11;
|
timer_dev *TIMER11 = &timer11;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(12)
|
#if STM32_HAVE_TIMER(12)
|
||||||
static timer_dev timer12 = RESTRICTED_GENERAL_TIMER(12, TIMER_DIER_TIE_BIT);
|
static timer_dev timer12 = RESTRICTED_GENERAL_TIMER(12, TIMER_DIER_TIE_BIT);
|
||||||
/** Timer 12 device (general-purpose) */
|
/** Timer 12 device (general-purpose) */
|
||||||
timer_dev *TIMER12 = &timer12;
|
timer_dev *TIMER12 = &timer12;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(13)
|
#if STM32_HAVE_TIMER(13)
|
||||||
static timer_dev timer13 = RESTRICTED_GENERAL_TIMER(13, TIMER_DIER_CC1IE_BIT);
|
static timer_dev timer13 = RESTRICTED_GENERAL_TIMER(13, TIMER_DIER_CC1IE_BIT);
|
||||||
/** Timer 13 device (general-purpose) */
|
/** Timer 13 device (general-purpose) */
|
||||||
timer_dev *TIMER13 = &timer13;
|
timer_dev *TIMER13 = &timer13;
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(14)
|
#if STM32_HAVE_TIMER(14)
|
||||||
static timer_dev timer14 = RESTRICTED_GENERAL_TIMER(14, TIMER_DIER_CC1IE_BIT);
|
static timer_dev timer14 = RESTRICTED_GENERAL_TIMER(14, TIMER_DIER_CC1IE_BIT);
|
||||||
/** Timer 14 device (general-purpose) */
|
/** Timer 14 device (general-purpose) */
|
||||||
timer_dev *TIMER14 = &timer14;
|
timer_dev *TIMER14 = &timer14;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routines
|
* Routines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Call a function on timer devices.
|
* @brief Call a function on timer devices.
|
||||||
* @param fn Function to call on each timer device.
|
* @param fn Function to call on each timer device.
|
||||||
*/
|
*/
|
||||||
void timer_foreach(void (*fn)(timer_dev*)) {
|
void timer_foreach(void (*fn)(timer_dev*)) {
|
||||||
#if STM32_HAVE_TIMER(1)
|
#if STM32_HAVE_TIMER(1)
|
||||||
fn(TIMER1);
|
fn(TIMER1);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(2)
|
#if STM32_HAVE_TIMER(2)
|
||||||
fn(TIMER2);
|
fn(TIMER2);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(3)
|
#if STM32_HAVE_TIMER(3)
|
||||||
fn(TIMER3);
|
fn(TIMER3);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(4)
|
#if STM32_HAVE_TIMER(4)
|
||||||
fn(TIMER4);
|
fn(TIMER4);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(5)
|
#if STM32_HAVE_TIMER(5)
|
||||||
fn(TIMER5);
|
fn(TIMER5);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(6)
|
#if STM32_HAVE_TIMER(6)
|
||||||
fn(TIMER6);
|
fn(TIMER6);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(7)
|
#if STM32_HAVE_TIMER(7)
|
||||||
fn(TIMER7);
|
fn(TIMER7);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(8)
|
#if STM32_HAVE_TIMER(8)
|
||||||
fn(TIMER8);
|
fn(TIMER8);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(9)
|
#if STM32_HAVE_TIMER(9)
|
||||||
fn(TIMER9);
|
fn(TIMER9);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(10)
|
#if STM32_HAVE_TIMER(10)
|
||||||
fn(TIMER10);
|
fn(TIMER10);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(11)
|
#if STM32_HAVE_TIMER(11)
|
||||||
fn(TIMER11);
|
fn(TIMER11);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(12)
|
#if STM32_HAVE_TIMER(12)
|
||||||
fn(TIMER12);
|
fn(TIMER12);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(13)
|
#if STM32_HAVE_TIMER(13)
|
||||||
fn(TIMER13);
|
fn(TIMER13);
|
||||||
#endif
|
#endif
|
||||||
#if STM32_HAVE_TIMER(14)
|
#if STM32_HAVE_TIMER(14)
|
||||||
fn(TIMER14);
|
fn(TIMER14);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a timer, and reset its register map.
|
* Initialize a timer, and reset its register map.
|
||||||
* @param dev Timer to initialize
|
* @param dev Timer to initialize
|
||||||
*/
|
*/
|
||||||
void timer_init(timer_dev *dev) {
|
void timer_init(timer_dev *dev) {
|
||||||
rcc_clk_enable(dev->clk_id);
|
rcc_clk_enable(dev->clk_id);
|
||||||
rcc_reset_dev(dev->clk_id);
|
rcc_reset_dev(dev->clk_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable a timer.
|
* @brief Disable a timer.
|
||||||
*
|
*
|
||||||
* The timer will stop counting, all DMA requests and interrupts will
|
* The timer will stop counting, all DMA requests and interrupts will
|
||||||
* be disabled, and no state changes will be output.
|
* be disabled, and no state changes will be output.
|
||||||
*
|
*
|
||||||
* @param dev Timer to disable.
|
* @param dev Timer to disable.
|
||||||
*/
|
*/
|
||||||
void timer_disable(timer_dev *dev) {
|
void timer_disable(timer_dev *dev) {
|
||||||
(dev->regs).bas->CR1 = 0;
|
(dev->regs).bas->CR1 = 0;
|
||||||
(dev->regs).bas->DIER = 0;
|
(dev->regs).bas->DIER = 0;
|
||||||
switch (dev->type) {
|
switch (dev->type) {
|
||||||
case TIMER_ADVANCED: /* fall-through */
|
case TIMER_ADVANCED: /* fall-through */
|
||||||
case TIMER_GENERAL:
|
case TIMER_GENERAL:
|
||||||
(dev->regs).gen->CCER = 0;
|
(dev->regs).gen->CCER = 0;
|
||||||
break;
|
break;
|
||||||
case TIMER_BASIC:
|
case TIMER_BASIC:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the mode of an individual timer channel.
|
* Sets the mode of an individual timer channel.
|
||||||
*
|
*
|
||||||
* Note that not all timers can be configured in every mode. For
|
* Note that not all timers can be configured in every mode. For
|
||||||
* example, basic timers cannot be configured to output compare mode.
|
* example, basic timers cannot be configured to output compare mode.
|
||||||
* Be sure to use a timer which is appropriate for the mode you want.
|
* Be sure to use a timer which is appropriate for the mode you want.
|
||||||
*
|
*
|
||||||
* @param dev Timer whose channel mode to set
|
* @param dev Timer whose channel mode to set
|
||||||
* @param channel Relevant channel
|
* @param channel Relevant channel
|
||||||
* @param mode New timer mode for channel
|
* @param mode New timer mode for channel
|
||||||
*/
|
*/
|
||||||
void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) {
|
void timer_set_mode(timer_dev *dev, uint8 channel, timer_mode mode) {
|
||||||
ASSERT_FAULT(channel > 0 && channel <= 4);
|
ASSERT_FAULT(channel > 0 && channel <= 4);
|
||||||
|
|
||||||
/* TODO decide about the basic timers */
|
/* TODO decide about the basic timers */
|
||||||
ASSERT(dev->type != TIMER_BASIC);
|
ASSERT(dev->type != TIMER_BASIC);
|
||||||
if (dev->type == TIMER_BASIC)
|
if (dev->type == TIMER_BASIC)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case TIMER_DISABLED:
|
case TIMER_DISABLED:
|
||||||
disable_channel(dev, channel);
|
disable_channel(dev, channel);
|
||||||
break;
|
break;
|
||||||
case TIMER_PWM:
|
case TIMER_PWM:
|
||||||
pwm_mode(dev, channel);
|
pwm_mode(dev, channel);
|
||||||
break;
|
break;
|
||||||
case TIMER_OUTPUT_COMPARE:
|
case TIMER_OUTPUT_COMPARE:
|
||||||
output_compare_mode(dev, channel);
|
output_compare_mode(dev, channel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Determine whether a timer has a particular capture/compare channel.
|
* @brief Determine whether a timer has a particular capture/compare channel.
|
||||||
*
|
*
|
||||||
* Different timers have different numbers of capture/compare channels
|
* Different timers have different numbers of capture/compare channels
|
||||||
* (and some have none at all). Use this function to test whether a
|
* (and some have none at all). Use this function to test whether a
|
||||||
* given timer/channel combination will work.
|
* given timer/channel combination will work.
|
||||||
*
|
*
|
||||||
* @param dev Timer device
|
* @param dev Timer device
|
||||||
* @param channel Capture/compare channel, from 1 to 4
|
* @param channel Capture/compare channel, from 1 to 4
|
||||||
* @return Nonzero if dev has channel, zero otherwise.
|
* @return Nonzero if dev has channel, zero otherwise.
|
||||||
*/
|
*/
|
||||||
int timer_has_cc_channel(timer_dev *dev, uint8 channel) {
|
int timer_has_cc_channel(timer_dev *dev, uint8 channel) {
|
||||||
/* On all currently supported series: advanced and "full-featured"
|
/* On all currently supported series: advanced and "full-featured"
|
||||||
* general purpose timers have all four channels. Of the
|
* general purpose timers have all four channels. Of the
|
||||||
* restricted general timers, timers 9 and 12 have channels 1 and
|
* restricted general timers, timers 9 and 12 have channels 1 and
|
||||||
* 2; the others have channel 1 only. Basic timers have none. */
|
* 2; the others have channel 1 only. Basic timers have none. */
|
||||||
rcc_clk_id id = dev->clk_id;
|
rcc_clk_id id = dev->clk_id;
|
||||||
ASSERT((1 <= channel) && (channel <= 4));
|
ASSERT((1 <= channel) && (channel <= 4));
|
||||||
if (id <= RCC_TIMER5 || id == RCC_TIMER8) {
|
if (id <= RCC_TIMER5 || id == RCC_TIMER8) {
|
||||||
return 1; /* 1 and 8 are advanced, 2-5 are "full" general */
|
return 1; /* 1 and 8 are advanced, 2-5 are "full" general */
|
||||||
} else if (id <= RCC_TIMER7) {
|
} else if (id <= RCC_TIMER7) {
|
||||||
return 0; /* 6 and 7 are basic */
|
return 0; /* 6 and 7 are basic */
|
||||||
}
|
}
|
||||||
/* The rest are restricted general. */
|
/* The rest are restricted general. */
|
||||||
return (((id == RCC_TIMER9 || id == RCC_TIMER12) && channel <= 2) ||
|
return (((id == RCC_TIMER9 || id == RCC_TIMER12) && channel <= 2) ||
|
||||||
channel == 1);
|
channel == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Attach a timer interrupt.
|
* @brief Attach a timer interrupt.
|
||||||
* @param dev Timer device
|
* @param dev Timer device
|
||||||
* @param interrupt Interrupt number to attach to; this may be any
|
* @param interrupt Interrupt number to attach to; this may be any
|
||||||
* timer_interrupt_id or timer_channel value appropriate
|
* timer_interrupt_id or timer_channel value appropriate
|
||||||
* for the timer.
|
* for the timer.
|
||||||
* @param handler Handler to attach to the given interrupt.
|
* @param handler Handler to attach to the given interrupt.
|
||||||
* @see timer_interrupt_id
|
* @see timer_interrupt_id
|
||||||
* @see timer_channel
|
* @see timer_channel
|
||||||
*/
|
*/
|
||||||
void timer_attach_interrupt(timer_dev *dev,
|
void timer_attach_interrupt(timer_dev *dev,
|
||||||
uint8 interrupt,
|
uint8 interrupt,
|
||||||
voidFuncPtr handler) {
|
voidFuncPtr handler) {
|
||||||
dev->handlers[interrupt] = handler;
|
dev->handlers[interrupt] = handler;
|
||||||
timer_enable_irq(dev, interrupt);
|
timer_enable_irq(dev, interrupt);
|
||||||
enable_irq(dev, interrupt);
|
enable_irq(dev, interrupt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Detach a timer interrupt.
|
* @brief Detach a timer interrupt.
|
||||||
* @param dev Timer device
|
* @param dev Timer device
|
||||||
* @param interrupt Interrupt number to detach; this may be any
|
* @param interrupt Interrupt number to detach; this may be any
|
||||||
* timer_interrupt_id or timer_channel value appropriate
|
* timer_interrupt_id or timer_channel value appropriate
|
||||||
* for the timer.
|
* for the timer.
|
||||||
* @see timer_interrupt_id
|
* @see timer_interrupt_id
|
||||||
* @see timer_channel
|
* @see timer_channel
|
||||||
*/
|
*/
|
||||||
void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) {
|
void timer_detach_interrupt(timer_dev *dev, uint8 interrupt) {
|
||||||
timer_disable_irq(dev, interrupt);
|
timer_disable_irq(dev, interrupt);
|
||||||
dev->handlers[interrupt] = NULL;
|
dev->handlers[interrupt] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utilities
|
* Utilities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void disable_channel(timer_dev *dev, uint8 channel) {
|
static void disable_channel(timer_dev *dev, uint8 channel) {
|
||||||
timer_detach_interrupt(dev, channel);
|
timer_detach_interrupt(dev, channel);
|
||||||
timer_cc_disable(dev, channel);
|
timer_cc_disable(dev, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pwm_mode(timer_dev *dev, uint8 channel) {
|
static void pwm_mode(timer_dev *dev, uint8 channel) {
|
||||||
timer_disable_irq(dev, channel);
|
timer_disable_irq(dev, channel);
|
||||||
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE);
|
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE);
|
||||||
timer_cc_enable(dev, channel);
|
timer_cc_enable(dev, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_compare_mode(timer_dev *dev, uint8 channel) {
|
static void output_compare_mode(timer_dev *dev, uint8 channel) {
|
||||||
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_ACTIVE_ON_MATCH, 0);
|
timer_oc_set_mode(dev, channel, TIMER_OC_MODE_ACTIVE_ON_MATCH, 0);
|
||||||
timer_cc_enable(dev, channel);
|
timer_cc_enable(dev, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id);
|
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id);
|
||||||
static void enable_bas_gen_irq(timer_dev *dev);
|
static void enable_bas_gen_irq(timer_dev *dev);
|
||||||
|
|
||||||
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) {
|
static inline void enable_irq(timer_dev *dev, timer_interrupt_id iid) {
|
||||||
if (dev->type == TIMER_ADVANCED) {
|
if (dev->type == TIMER_ADVANCED) {
|
||||||
enable_adv_irq(dev, iid);
|
enable_adv_irq(dev, iid);
|
||||||
} else {
|
} else {
|
||||||
enable_bas_gen_irq(dev);
|
enable_bas_gen_irq(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Advanced control timers have several IRQ lines corresponding to
|
/* Advanced control timers have several IRQ lines corresponding to
|
||||||
* different timer interrupts.
|
* different timer interrupts.
|
||||||
*
|
*
|
||||||
* Note: This function assumes that the only advanced timers are TIM1
|
* Note: This function assumes that the only advanced timers are TIM1
|
||||||
* and TIM8, and needs the obvious changes if that assumption is
|
* and TIM8, and needs the obvious changes if that assumption is
|
||||||
* violated by a later STM32 series. */
|
* violated by a later STM32 series. */
|
||||||
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id) {
|
static void enable_adv_irq(timer_dev *dev, timer_interrupt_id id) {
|
||||||
uint8 is_tim1 = dev->clk_id == RCC_TIMER1;
|
uint8 is_tim1 = dev->clk_id == RCC_TIMER1;
|
||||||
nvic_irq_num irq_num;
|
nvic_irq_num irq_num;
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case TIMER_UPDATE_INTERRUPT:
|
case TIMER_UPDATE_INTERRUPT:
|
||||||
irq_num = (is_tim1 ?
|
irq_num = (is_tim1 ?
|
||||||
NVIC_TIMER1_UP_TIMER10 :
|
NVIC_TIMER1_UP_TIMER10 :
|
||||||
NVIC_TIMER8_UP_TIMER13);
|
NVIC_TIMER8_UP_TIMER13);
|
||||||
break;
|
break;
|
||||||
case TIMER_CC1_INTERRUPT: /* Fall through */
|
case TIMER_CC1_INTERRUPT: /* Fall through */
|
||||||
case TIMER_CC2_INTERRUPT: /* ... */
|
case TIMER_CC2_INTERRUPT: /* ... */
|
||||||
case TIMER_CC3_INTERRUPT: /* ... */
|
case TIMER_CC3_INTERRUPT: /* ... */
|
||||||
case TIMER_CC4_INTERRUPT:
|
case TIMER_CC4_INTERRUPT:
|
||||||
irq_num = is_tim1 ? NVIC_TIMER1_CC : NVIC_TIMER8_CC;
|
irq_num = is_tim1 ? NVIC_TIMER1_CC : NVIC_TIMER8_CC;
|
||||||
break;
|
break;
|
||||||
case TIMER_COM_INTERRUPT: /* Fall through */
|
case TIMER_COM_INTERRUPT: /* Fall through */
|
||||||
case TIMER_TRG_INTERRUPT:
|
case TIMER_TRG_INTERRUPT:
|
||||||
irq_num = (is_tim1 ?
|
irq_num = (is_tim1 ?
|
||||||
NVIC_TIMER1_TRG_COM_TIMER11 :
|
NVIC_TIMER1_TRG_COM_TIMER11 :
|
||||||
NVIC_TIMER8_TRG_COM_TIMER14);
|
NVIC_TIMER8_TRG_COM_TIMER14);
|
||||||
break;
|
break;
|
||||||
case TIMER_BREAK_INTERRUPT:
|
case TIMER_BREAK_INTERRUPT:
|
||||||
irq_num = (is_tim1 ?
|
irq_num = (is_tim1 ?
|
||||||
NVIC_TIMER1_BRK_TIMER9 :
|
NVIC_TIMER1_BRK_TIMER9 :
|
||||||
NVIC_TIMER8_BRK_TIMER12);
|
NVIC_TIMER8_BRK_TIMER12);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Can't happen, but placate the compiler */
|
/* Can't happen, but placate the compiler */
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nvic_irq_enable(irq_num);
|
nvic_irq_enable(irq_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Basic and general purpose timers have a single IRQ line, which is
|
/* Basic and general purpose timers have a single IRQ line, which is
|
||||||
* shared by all interrupts supported by a particular timer. */
|
* shared by all interrupts supported by a particular timer. */
|
||||||
static void enable_bas_gen_irq(timer_dev *dev) {
|
static void enable_bas_gen_irq(timer_dev *dev) {
|
||||||
nvic_irq_num irq_num;
|
nvic_irq_num irq_num;
|
||||||
switch (dev->clk_id) {
|
switch (dev->clk_id) {
|
||||||
case RCC_TIMER2:
|
case RCC_TIMER2:
|
||||||
irq_num = NVIC_TIMER2;
|
irq_num = NVIC_TIMER2;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER3:
|
case RCC_TIMER3:
|
||||||
irq_num = NVIC_TIMER3;
|
irq_num = NVIC_TIMER3;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER4:
|
case RCC_TIMER4:
|
||||||
irq_num = NVIC_TIMER4;
|
irq_num = NVIC_TIMER4;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER5:
|
case RCC_TIMER5:
|
||||||
irq_num = NVIC_TIMER5;
|
irq_num = NVIC_TIMER5;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER6:
|
case RCC_TIMER6:
|
||||||
irq_num = NVIC_TIMER6;
|
irq_num = NVIC_TIMER6;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER7:
|
case RCC_TIMER7:
|
||||||
irq_num = NVIC_TIMER7;
|
irq_num = NVIC_TIMER7;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER9:
|
case RCC_TIMER9:
|
||||||
irq_num = NVIC_TIMER1_BRK_TIMER9;
|
irq_num = NVIC_TIMER1_BRK_TIMER9;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER10:
|
case RCC_TIMER10:
|
||||||
irq_num = NVIC_TIMER1_UP_TIMER10;
|
irq_num = NVIC_TIMER1_UP_TIMER10;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER11:
|
case RCC_TIMER11:
|
||||||
irq_num = NVIC_TIMER1_TRG_COM_TIMER11;
|
irq_num = NVIC_TIMER1_TRG_COM_TIMER11;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER12:
|
case RCC_TIMER12:
|
||||||
irq_num = NVIC_TIMER8_BRK_TIMER12;
|
irq_num = NVIC_TIMER8_BRK_TIMER12;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER13:
|
case RCC_TIMER13:
|
||||||
irq_num = NVIC_TIMER8_UP_TIMER13;
|
irq_num = NVIC_TIMER8_UP_TIMER13;
|
||||||
break;
|
break;
|
||||||
case RCC_TIMER14:
|
case RCC_TIMER14:
|
||||||
irq_num = NVIC_TIMER8_TRG_COM_TIMER14;
|
irq_num = NVIC_TIMER8_TRG_COM_TIMER14;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_FAULT(0);
|
ASSERT_FAULT(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nvic_irq_enable(irq_num);
|
nvic_irq_enable(irq_num);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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_mini/board.cpp
|
||||||
|
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||||
|
* @brief Maple Mini board file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <board/board.h>
|
||||||
|
|
||||||
|
#include <libmaple/gpio.h>
|
||||||
|
#include <libmaple/timer.h>
|
||||||
|
|
||||||
|
#include <wirish_debug.h>
|
||||||
|
#include <wirish_types.h>
|
||||||
|
|
||||||
|
/* Since we want the Serial Wire/JTAG pins as GPIOs, disable both SW
|
||||||
|
* and JTAG debug support, unless configured otherwise. */
|
||||||
|
void boardInit(void) {
|
||||||
|
#ifndef CONFIG_MAPLE_MINI_NO_DISABLE_DEBUG
|
||||||
|
disableDebugPorts();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = {
|
||||||
|
|
||||||
|
/* Top header */
|
||||||
|
{GPIOA, TIMER2, ADC1, 0, 1, 0}, /* D11/PA0 */
|
||||||
|
{GPIOA, TIMER2, ADC1, 1, 2, 1}, /* D10/PA1 */
|
||||||
|
{GPIOA, TIMER2, ADC1, 2, 3, 2}, /* D9/PA2 */
|
||||||
|
{GPIOA, TIMER2, ADC1, 3, 4, 3}, /* D8/PA3 */
|
||||||
|
{GPIOA, NULL, ADC1, 4, 0, 4}, /* D7/PA4 */
|
||||||
|
{GPIOA, NULL, ADC1, 5, 0, 5}, /* D6/PA5 */
|
||||||
|
{GPIOA, TIMER3, ADC1, 6, 1, 6}, /* D5/PA6 */
|
||||||
|
{GPIOA, TIMER3, ADC1, 7, 2, 7}, /* D4/PA7 */
|
||||||
|
{GPIOA, TIMER1, NULL, 8, 1, ADCx}, /* D27/PA8 */
|
||||||
|
{GPIOA, TIMER1, NULL, 9, 2, ADCx}, /* D26/PA9 */
|
||||||
|
{GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D25/PA10 */
|
||||||
|
{GPIOA, TIMER1, NULL, 11, 4, ADCx}, /* D24/PA11 */
|
||||||
|
{GPIOA, NULL, NULL, 12, 0, ADCx}, /* D23/PA12 */
|
||||||
|
{GPIOA, NULL, NULL, 13, 0, ADCx}, /* D22/PA13 */
|
||||||
|
{GPIOA, NULL, NULL, 14, 0, ADCx}, /* D21/PA14 */
|
||||||
|
{GPIOA, NULL, NULL, 15, 0, ADCx}, /* D20/PA15 */
|
||||||
|
|
||||||
|
{GPIOB, TIMER3, ADC1, 0, 3, 8}, /* D3/PB0 */
|
||||||
|
{GPIOB, NULL, NULL, 11, 0, ADCx}, /* D0/PB11 */
|
||||||
|
{GPIOB, NULL, NULL, 10, 0, ADCx}, /* D1/PB10 */
|
||||||
|
{GPIOB, NULL, NULL, 2, 0, ADCx}, /* D2/PB2 */
|
||||||
|
|
||||||
|
|
||||||
|
{GPIOC, NULL, NULL, 15, 0, ADCx}, /* D12/PC15 */
|
||||||
|
{GPIOC, NULL, NULL, 14, 0, ADCx}, /* D13/PC14 */
|
||||||
|
{GPIOC, NULL, NULL, 13, 0, ADCx}, /* D14/PC13 */
|
||||||
|
|
||||||
|
/* Bottom header */
|
||||||
|
|
||||||
|
{GPIOB, TIMER4, NULL, 7, 2, ADCx}, /* D15/PB7 */
|
||||||
|
{GPIOB, TIMER4, NULL, 6, 1, ADCx}, /* D16/PB6 */
|
||||||
|
{GPIOB, NULL, NULL, 5, 0, ADCx}, /* D17/PB5 */
|
||||||
|
{GPIOB, NULL, NULL, 4, 0, ADCx}, /* D18/PB4 */
|
||||||
|
{GPIOB, NULL, NULL, 3, 0, ADCx}, /* D19/PB3 */
|
||||||
|
|
||||||
|
|
||||||
|
{GPIOB, NULL, NULL, 15, 0, ADCx}, /* D28/PB15 */
|
||||||
|
{GPIOB, NULL, NULL, 14, 0, ADCx}, /* D29/PB14 */
|
||||||
|
{GPIOB, NULL, NULL, 13, 0, ADCx}, /* D30/PB13 */
|
||||||
|
{GPIOB, NULL, NULL, 12, 0, ADCx}, /* D31/PB12 */
|
||||||
|
{GPIOB, TIMER4, NULL, 8, 3, ADCx}, /* D32/PB8 */
|
||||||
|
{GPIOB, TIMER3, ADC1, 1, 4, 9}, /* D33/PB1 */
|
||||||
|
{GPIOB, NULL, NULL, 9, 0, ADCx}, /* PB9 */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = {
|
||||||
|
PB0, PA7, PA6, PA3, PA2, PA1, PA0, PB7, PB6, PA10, PA9, PA8
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
old maple mini mapping enum
|
||||||
|
PB11, PB10, PB2, PB0, PA7, PA6, PA5, PA4, PA3, PA2, PA1, PA0, PC15, PC14,
|
||||||
|
PC13, PB7, PB6, PB5, PB4, PB3, PA15, PA14, PA13, PA12, PA11, PA10, PA9,
|
||||||
|
PA8, PB15, PB14, PB13, PB12, PB8, PB1
|
||||||
|
*/
|
||||||
|
extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = {
|
||||||
|
PB0, PA7, PA6 , PA5 , PA4 , PA3 , PA2 , PA1 , PA0
|
||||||
|
};
|
||||||
|
|
||||||
|
#define USB_DP PA12
|
||||||
|
#define USB_DM PA11
|
||||||
|
|
||||||
|
extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
|
||||||
|
BOARD_LED_PIN, BOARD_BUTTON_PIN, USB_DP, USB_DM
|
||||||
|
};
|
|
@ -0,0 +1,86 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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_mini/include/board/board.h
|
||||||
|
* @author Marti Bolivar <mbolivar@leaflabs.com>
|
||||||
|
* @brief Maple Mini board header.
|
||||||
|
*
|
||||||
|
* See wirish/boards/maple/include/board/board.h for more information
|
||||||
|
* on these definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BOARD_GENERIC_STM32F103C_H_
|
||||||
|
#define _BOARD_GENERIC_STM32F103C_H_
|
||||||
|
|
||||||
|
#define CYCLES_PER_MICROSECOND 72
|
||||||
|
#define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */
|
||||||
|
|
||||||
|
#define BOARD_BUTTON_PIN 32
|
||||||
|
#define BOARD_LED_PIN 33
|
||||||
|
|
||||||
|
#define BOARD_NR_USARTS 3
|
||||||
|
#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
|
||||||
|
|
||||||
|
#define BOARD_NR_SPI 2
|
||||||
|
#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 PB12
|
||||||
|
#define BOARD_SPI2_MOSI_PIN PB15
|
||||||
|
#define BOARD_SPI2_MISO_PIN PB14
|
||||||
|
#define BOARD_SPI2_SCK_PIN PB13
|
||||||
|
|
||||||
|
#define BOARD_NR_GPIO_PINS 35
|
||||||
|
#define BOARD_NR_PWM_PINS 12
|
||||||
|
#define BOARD_NR_ADC_PINS 9
|
||||||
|
#define BOARD_NR_USED_PINS 4
|
||||||
|
|
||||||
|
|
||||||
|
#define BOARD_JTMS_SWDIO_PIN 22
|
||||||
|
#define BOARD_JTCK_SWCLK_PIN 21
|
||||||
|
#define BOARD_JTDI_PIN 20
|
||||||
|
#define BOARD_JTDO_PIN 19
|
||||||
|
#define BOARD_NJTRST_PIN 18
|
||||||
|
|
||||||
|
#define BOARD_USB_DISC_DEV GPIOB
|
||||||
|
#define BOARD_USB_DISC_BIT 10
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9,PA10,PA11,PA12,PA13,PA14,PA15,
|
||||||
|
PB0,PB11, PB10, PB2, PC15, PC14,
|
||||||
|
PC13, PB7, PB6, PB5, PB4, PB3, PB15, PB14, PB13, PB12, PB8, PB1, PB9
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* Linker script for libmaple.
|
||||||
|
*
|
||||||
|
* Original author "lanchon" from ST forums, with modifications by LeafLabs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure other libraries we want in the link.
|
||||||
|
*
|
||||||
|
* libgcc, libc, and libm are common across supported toolchains.
|
||||||
|
* However, some toolchains require additional archives which aren't
|
||||||
|
* present everywhere (e.g. ARM's gcc-arm-embedded releases).
|
||||||
|
*
|
||||||
|
* To hack around this, we let the build system specify additional
|
||||||
|
* archives by putting the right extra_libs.inc (in a directory under
|
||||||
|
* toolchains/) in our search path.
|
||||||
|
*/
|
||||||
|
GROUP(libgcc.a libc.a libm.a)
|
||||||
|
INCLUDE extra_libs.inc
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These force the linker to search for vector table symbols.
|
||||||
|
*
|
||||||
|
* These symbols vary by STM32 family (and also within families).
|
||||||
|
* It's up to the build system to configure the link's search path
|
||||||
|
* properly for the target MCU.
|
||||||
|
*/
|
||||||
|
INCLUDE vector_symbols.inc
|
||||||
|
|
||||||
|
/* STM32 vector table. */
|
||||||
|
EXTERN(__stm32_vector_table)
|
||||||
|
|
||||||
|
/* C runtime initialization function. */
|
||||||
|
EXTERN(start_c)
|
||||||
|
|
||||||
|
/* main entry point */
|
||||||
|
EXTERN(main)
|
||||||
|
|
||||||
|
/* Initial stack pointer value. */
|
||||||
|
EXTERN(__msp_init)
|
||||||
|
PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram));
|
||||||
|
|
||||||
|
/* Reset vector and chip reset entry point */
|
||||||
|
EXTERN(__start__)
|
||||||
|
ENTRY(__start__)
|
||||||
|
PROVIDE(__exc_reset = __start__);
|
||||||
|
|
||||||
|
/* Heap boundaries, for libmaple */
|
||||||
|
EXTERN(_lm_heap_start);
|
||||||
|
EXTERN(_lm_heap_end);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
__text_start__ = .;
|
||||||
|
/*
|
||||||
|
* STM32 vector table. Leave this here. Yes, really.
|
||||||
|
*/
|
||||||
|
*(.stm32.interrupt_vector)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Program code and vague linking
|
||||||
|
*/
|
||||||
|
*(.text .text.* .gnu.linkonce.t.*)
|
||||||
|
*(.plt)
|
||||||
|
*(.gnu.warning)
|
||||||
|
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||||
|
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
*(.gcc_except_table)
|
||||||
|
*(.eh_frame_hdr)
|
||||||
|
*(.eh_frame)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.init))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__preinit_array_start = .;
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
__preinit_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
__init_array_end = .;
|
||||||
|
|
||||||
|
. = ALIGN(0x4);
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*crtend.o(.ctors))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
__fini_array_start = .;
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
__fini_array_end = .;
|
||||||
|
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*crtend.o(.dtors))
|
||||||
|
} > REGION_TEXT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* End of text
|
||||||
|
*/
|
||||||
|
.text.align :
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
__text_end__ = .;
|
||||||
|
} > REGION_TEXT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* .ARM.exidx exception unwinding; mandated by ARM's C++ ABI
|
||||||
|
*/
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > REGION_RODATA
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* .data
|
||||||
|
*/
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN(8);
|
||||||
|
|
||||||
|
*(.got.plt) *(.got)
|
||||||
|
*(.data .data.* .gnu.linkonce.d.*)
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
__data_end__ = .;
|
||||||
|
} > REGION_DATA AT> REGION_RODATA
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read-only data
|
||||||
|
*/
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||||
|
/* .USER_FLASH: We allow users to allocate into Flash here */
|
||||||
|
*(.USER_FLASH)
|
||||||
|
/* ROM image configuration; for C startup */
|
||||||
|
. = ALIGN(4);
|
||||||
|
_lm_rom_img_cfgp = .;
|
||||||
|
LONG(LOADADDR(.data));
|
||||||
|
/*
|
||||||
|
* Heap: Linker scripts may choose a custom heap by overriding
|
||||||
|
* _lm_heap_start and _lm_heap_end. Otherwise, the heap is in
|
||||||
|
* internal SRAM, beginning after .bss, and growing towards
|
||||||
|
* the stack.
|
||||||
|
*
|
||||||
|
* I'm shoving these here naively; there's probably a cleaner way
|
||||||
|
* to go about this. [mbolivar]
|
||||||
|
*/
|
||||||
|
_lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end;
|
||||||
|
_lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init;
|
||||||
|
} > REGION_RODATA
|
||||||
|
|
||||||
|
/*
|
||||||
|
* .bss
|
||||||
|
*/
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(8);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN (8);
|
||||||
|
__bss_end__ = .;
|
||||||
|
_end = __bss_end__;
|
||||||
|
} > REGION_BSS
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debugging sections
|
||||||
|
*/
|
||||||
|
.stab 0 (NOLOAD) : { *(.stab) }
|
||||||
|
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
||||||
|
/* DWARF debug sections.
|
||||||
|
* Symbols in the DWARF debugging sections are relative to the beginning
|
||||||
|
* of the section so we begin them at 0. */
|
||||||
|
/* DWARF 1 */
|
||||||
|
.debug 0 : { *(.debug) }
|
||||||
|
.line 0 : { *(.line) }
|
||||||
|
/* GNU DWARF 1 extensions */
|
||||||
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
/* DWARF 2 */
|
||||||
|
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||||
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
|
.debug_line 0 : { *(.debug_line) }
|
||||||
|
.debug_frame 0 : { *(.debug_frame) }
|
||||||
|
.debug_str 0 : { *(.debug_str) }
|
||||||
|
.debug_loc 0 : { *(.debug_loc) }
|
||||||
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
/* SGI/MIPS DWARF 2 extensions */
|
||||||
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||||
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||||
|
.debug_typenames 0 : { *(.debug_typenames) }
|
||||||
|
.debug_varnames 0 : { *(.debug_varnames) }
|
||||||
|
|
||||||
|
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||||
|
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||||
|
/DISCARD/ : { *(.note.GNU-stack) }
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi-
|
||||||
|
* releases (https://launchpad.net/gcc-arm-embedded/).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is for the provided newlib. */
|
||||||
|
GROUP(libnosys.a)
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* libmaple linker script for "Flash" builds.
|
||||||
|
*
|
||||||
|
* A Flash build puts .text (and .rodata) in Flash, and
|
||||||
|
* .data/.bss/heap (of course) in SRAM, but offsets the sections by
|
||||||
|
* enough space to store the Maple bootloader, which lives in low
|
||||||
|
* Flash and uses low memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This pulls in the appropriate MEMORY declaration from the right
|
||||||
|
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||||
|
* right include directory flags to make this happen). Boards can also
|
||||||
|
* use this file to use any of libmaple's memory-related hooks (like
|
||||||
|
* where the heap should live).
|
||||||
|
*/
|
||||||
|
INCLUDE mem-flash.inc
|
||||||
|
|
||||||
|
/* Provide memory region aliases for common.inc */
|
||||||
|
REGION_ALIAS("REGION_TEXT", rom);
|
||||||
|
REGION_ALIAS("REGION_DATA", ram);
|
||||||
|
REGION_ALIAS("REGION_BSS", ram);
|
||||||
|
REGION_ALIAS("REGION_RODATA", rom);
|
||||||
|
|
||||||
|
/* Let common.inc handle the real work. */
|
||||||
|
INCLUDE common.inc
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* libmaple linker script for "Flash" builds.
|
||||||
|
*
|
||||||
|
* A Flash build puts .text (and .rodata) in Flash, and
|
||||||
|
* .data/.bss/heap (of course) in SRAM, but offsets the sections by
|
||||||
|
* enough space to store the Maple bootloader, which lives in low
|
||||||
|
* Flash and uses low memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This pulls in the appropriate MEMORY declaration from the right
|
||||||
|
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||||
|
* right include directory flags to make this happen). Boards can also
|
||||||
|
* use this file to use any of libmaple's memory-related hooks (like
|
||||||
|
* where the heap should live).
|
||||||
|
*/
|
||||||
|
/*INCLUDE mem-flash.inc*/
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 44K
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Provide memory region aliases for common.inc */
|
||||||
|
REGION_ALIAS("REGION_TEXT", rom);
|
||||||
|
REGION_ALIAS("REGION_DATA", ram);
|
||||||
|
REGION_ALIAS("REGION_BSS", ram);
|
||||||
|
REGION_ALIAS("REGION_RODATA", rom);
|
||||||
|
|
||||||
|
/* Let common.inc handle the real work. */
|
||||||
|
INCLUDE common.inc
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* libmaple linker script for "JTAG" builds.
|
||||||
|
*
|
||||||
|
* A "JTAG" build puts .text (and .rodata) in Flash, and
|
||||||
|
* .data/.bss/heap (of course) in SRAM, but links starting at the
|
||||||
|
* Flash and SRAM starting addresses (0x08000000 and 0x20000000
|
||||||
|
* respectively). This will wipe out a Maple bootloader if there's one
|
||||||
|
* on the board, so only use this if you know what you're doing.
|
||||||
|
*
|
||||||
|
* Of course, a "JTAG" build is perfectly usable for upload over SWD,
|
||||||
|
* the system memory bootloader, etc. The name is just a historical
|
||||||
|
* artifact.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This pulls in the appropriate MEMORY declaration from the right
|
||||||
|
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||||
|
* right include directory flags to make this happen). Boards can also
|
||||||
|
* use this file to use any of libmaple's memory-related hooks (like
|
||||||
|
* where the heap should live).
|
||||||
|
*/
|
||||||
|
INCLUDE mem-jtag.inc
|
||||||
|
|
||||||
|
/* Provide memory region aliases for common.inc */
|
||||||
|
REGION_ALIAS("REGION_TEXT", rom);
|
||||||
|
REGION_ALIAS("REGION_DATA", ram);
|
||||||
|
REGION_ALIAS("REGION_BSS", ram);
|
||||||
|
REGION_ALIAS("REGION_RODATA", rom);
|
||||||
|
|
||||||
|
/* Let common.inc handle the real work. */
|
||||||
|
INCLUDE common.inc
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* libmaple linker script for "JTAG" builds.
|
||||||
|
*
|
||||||
|
* A "JTAG" build puts .text (and .rodata) in Flash, and
|
||||||
|
* .data/.bss/heap (of course) in SRAM, but links starting at the
|
||||||
|
* Flash and SRAM starting addresses (0x08000000 and 0x20000000
|
||||||
|
* respectively). This will wipe out a Maple bootloader if there's one
|
||||||
|
* on the board, so only use this if you know what you're doing.
|
||||||
|
*
|
||||||
|
* Of course, a "JTAG" build is perfectly usable for upload over SWD,
|
||||||
|
* the system memory bootloader, etc. The name is just a historical
|
||||||
|
* artifact.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This pulls in the appropriate MEMORY declaration from the right
|
||||||
|
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||||
|
* right include directory flags to make this happen). Boards can also
|
||||||
|
* use this file to use any of libmaple's memory-related hooks (like
|
||||||
|
* where the heap should live).
|
||||||
|
*/
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Provide memory region aliases for common.inc */
|
||||||
|
REGION_ALIAS("REGION_TEXT", rom);
|
||||||
|
REGION_ALIAS("REGION_DATA", ram);
|
||||||
|
REGION_ALIAS("REGION_BSS", ram);
|
||||||
|
REGION_ALIAS("REGION_RODATA", rom);
|
||||||
|
|
||||||
|
/* Let common.inc handle the real work. */
|
||||||
|
INCLUDE common.inc
|
|
@ -0,0 +1,5 @@
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
|
||||||
|
rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
|
||||||
|
rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* libmaple linker script for RAM builds.
|
||||||
|
*
|
||||||
|
* A Flash build puts .text, .rodata, and .data/.bss/heap (of course)
|
||||||
|
* in SRAM, but offsets the sections by enough space to store the
|
||||||
|
* Maple bootloader, which uses low memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This pulls in the appropriate MEMORY declaration from the right
|
||||||
|
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||||
|
* right include directory flags to make this happen). Boards can also
|
||||||
|
* use this file to use any of libmaple's memory-related hooks (like
|
||||||
|
* where the heap should live).
|
||||||
|
*/
|
||||||
|
INCLUDE mem-ram.inc
|
||||||
|
|
||||||
|
/* Provide memory region aliases for common.inc */
|
||||||
|
REGION_ALIAS("REGION_TEXT", ram);
|
||||||
|
REGION_ALIAS("REGION_DATA", ram);
|
||||||
|
REGION_ALIAS("REGION_BSS", ram);
|
||||||
|
REGION_ALIAS("REGION_RODATA", ram);
|
||||||
|
|
||||||
|
/* Let common.inc handle the real work. */
|
||||||
|
INCLUDE common.inc
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* libmaple linker script for RAM builds.
|
||||||
|
*
|
||||||
|
* A Flash build puts .text, .rodata, and .data/.bss/heap (of course)
|
||||||
|
* in SRAM, but offsets the sections by enough space to store the
|
||||||
|
* Maple bootloader, which uses low memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This pulls in the appropriate MEMORY declaration from the right
|
||||||
|
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||||
|
* right include directory flags to make this happen). Boards can also
|
||||||
|
* use this file to use any of libmaple's memory-related hooks (like
|
||||||
|
* where the heap should live).
|
||||||
|
*/
|
||||||
|
/*INCLUDE mem-ram.inc*/
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
|
||||||
|
rom (rx) : ORIGIN = 0x08005000, LENGTH = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Provide memory region aliases for common.inc */
|
||||||
|
REGION_ALIAS("REGION_TEXT", ram);
|
||||||
|
REGION_ALIAS("REGION_DATA", ram);
|
||||||
|
REGION_ALIAS("REGION_BSS", ram);
|
||||||
|
REGION_ALIAS("REGION_RODATA", ram);
|
||||||
|
|
||||||
|
/* Let common.inc handle the real work. */
|
||||||
|
INCLUDE common.inc
|
|
@ -0,0 +1,78 @@
|
||||||
|
EXTERN(__msp_init)
|
||||||
|
EXTERN(__exc_reset)
|
||||||
|
EXTERN(__exc_nmi)
|
||||||
|
EXTERN(__exc_hardfault)
|
||||||
|
EXTERN(__exc_memmanage)
|
||||||
|
EXTERN(__exc_busfault)
|
||||||
|
EXTERN(__exc_usagefault)
|
||||||
|
EXTERN(__stm32reservedexception7)
|
||||||
|
EXTERN(__stm32reservedexception8)
|
||||||
|
EXTERN(__stm32reservedexception9)
|
||||||
|
EXTERN(__stm32reservedexception10)
|
||||||
|
EXTERN(__exc_svc)
|
||||||
|
EXTERN(__exc_debug_monitor)
|
||||||
|
EXTERN(__stm32reservedexception13)
|
||||||
|
EXTERN(__exc_pendsv)
|
||||||
|
EXTERN(__exc_systick)
|
||||||
|
|
||||||
|
EXTERN(__irq_wwdg)
|
||||||
|
EXTERN(__irq_pvd)
|
||||||
|
EXTERN(__irq_tamper)
|
||||||
|
EXTERN(__irq_rtc)
|
||||||
|
EXTERN(__irq_flash)
|
||||||
|
EXTERN(__irq_rcc)
|
||||||
|
EXTERN(__irq_exti0)
|
||||||
|
EXTERN(__irq_exti1)
|
||||||
|
EXTERN(__irq_exti2)
|
||||||
|
EXTERN(__irq_exti3)
|
||||||
|
EXTERN(__irq_exti4)
|
||||||
|
EXTERN(__irq_dma1_channel1)
|
||||||
|
EXTERN(__irq_dma1_channel2)
|
||||||
|
EXTERN(__irq_dma1_channel3)
|
||||||
|
EXTERN(__irq_dma1_channel4)
|
||||||
|
EXTERN(__irq_dma1_channel5)
|
||||||
|
EXTERN(__irq_dma1_channel6)
|
||||||
|
EXTERN(__irq_dma1_channel7)
|
||||||
|
EXTERN(__irq_adc)
|
||||||
|
EXTERN(__irq_usb_hp_can_tx)
|
||||||
|
EXTERN(__irq_usb_lp_can_rx0)
|
||||||
|
EXTERN(__irq_can_rx1)
|
||||||
|
EXTERN(__irq_can_sce)
|
||||||
|
EXTERN(__irq_exti9_5)
|
||||||
|
EXTERN(__irq_tim1_brk)
|
||||||
|
EXTERN(__irq_tim1_up)
|
||||||
|
EXTERN(__irq_tim1_trg_com)
|
||||||
|
EXTERN(__irq_tim1_cc)
|
||||||
|
EXTERN(__irq_tim2)
|
||||||
|
EXTERN(__irq_tim3)
|
||||||
|
EXTERN(__irq_tim4)
|
||||||
|
EXTERN(__irq_i2c1_ev)
|
||||||
|
EXTERN(__irq_i2c1_er)
|
||||||
|
EXTERN(__irq_i2c2_ev)
|
||||||
|
EXTERN(__irq_i2c2_er)
|
||||||
|
EXTERN(__irq_spi1)
|
||||||
|
EXTERN(__irq_spi2)
|
||||||
|
EXTERN(__irq_usart1)
|
||||||
|
EXTERN(__irq_usart2)
|
||||||
|
EXTERN(__irq_usart3)
|
||||||
|
EXTERN(__irq_exti15_10)
|
||||||
|
EXTERN(__irq_rtcalarm)
|
||||||
|
EXTERN(__irq_usbwakeup)
|
||||||
|
|
||||||
|
EXTERN(__irq_tim8_brk)
|
||||||
|
EXTERN(__irq_tim8_up)
|
||||||
|
EXTERN(__irq_tim8_trg_com)
|
||||||
|
EXTERN(__irq_tim8_cc)
|
||||||
|
EXTERN(__irq_adc3)
|
||||||
|
EXTERN(__irq_fsmc)
|
||||||
|
EXTERN(__irq_sdio)
|
||||||
|
EXTERN(__irq_tim5)
|
||||||
|
EXTERN(__irq_spi3)
|
||||||
|
EXTERN(__irq_uart4)
|
||||||
|
EXTERN(__irq_uart5)
|
||||||
|
EXTERN(__irq_tim6)
|
||||||
|
EXTERN(__irq_tim7)
|
||||||
|
EXTERN(__irq_dma2_channel1)
|
||||||
|
EXTERN(__irq_dma2_channel2)
|
||||||
|
EXTERN(__irq_dma2_channel3)
|
||||||
|
EXTERN(__irq_dma2_channel4_5)
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// API compatibility
|
||||||
|
#include "variant.h"
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef _VARIANT_ARDUINO_STM32_
|
||||||
|
#define _VARIANT_ARDUINO_STM32_
|
||||||
|
|
||||||
|
#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device )
|
||||||
|
#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) )
|
||||||
|
#define portOutputRegister(port) ( &(port->regs->ODR) )
|
||||||
|
#define portInputRegister(port) ( &(port->regs->IDR) )
|
||||||
|
|
||||||
|
#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) )
|
||||||
|
#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) )
|
||||||
|
|
||||||
|
#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) )
|
||||||
|
|
||||||
|
#endif /* _VARIANT_ARDUINO_STM32_ */
|
|
@ -0,0 +1,223 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Perry Hung.
|
||||||
|
* Copyright (c) 2011, 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.cpp
|
||||||
|
* @brief init() and board routines.
|
||||||
|
*
|
||||||
|
* This file is mostly interesting for the init() function, which
|
||||||
|
* 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
|
||||||
|
* things on before using them.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* How init() works is chip-specific. See the boards_setup.cpp files
|
||||||
|
* under e.g. wirish/stm32f1/, wirish/stmf32f2 for the details, but be
|
||||||
|
* advised: their contents are unstable, and can/will change without
|
||||||
|
* notice.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boards.h>
|
||||||
|
#include <libmaple/libmaple_types.h>
|
||||||
|
#include <libmaple/flash.h>
|
||||||
|
#include <libmaple/nvic.h>
|
||||||
|
#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();
|
||||||
|
setup_nvic();
|
||||||
|
systick_init(SYSTICK_RELOAD_VAL);
|
||||||
|
wirish::priv::board_setup_gpio();
|
||||||
|
setup_adcs();
|
||||||
|
setup_timers();
|
||||||
|
wirish::priv::board_setup_usb();
|
||||||
|
wirish::priv::series_init();
|
||||||
|
boardInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Provide a default no-op boardInit(). */
|
||||||
|
__weak void boardInit(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
bool boardUsesPin(uint8 pin) {
|
||||||
|
for (int i = 0; i < BOARD_NR_USED_PINS; i++) {
|
||||||
|
if (pin == boardUsedPins[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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::w_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
#else
|
||||||
|
#if defined(BOOTLOADER_robotis)
|
||||||
|
#define USER_ADDR_ROM 0x08003000
|
||||||
|
#else
|
||||||
|
#define USER_ADDR_ROM 0x08000000
|
||||||
|
#endif
|
||||||
|
#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) {
|
||||||
|
adc_set_prescaler(wirish::priv::w_adc_pre);
|
||||||
|
adc_foreach(adc_default_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timer_default_config(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 (uint8 channel = 1; channel <= 4; channel++) {
|
||||||
|
if (timer_has_cc_channel(dev, 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_generate_update(dev);
|
||||||
|
timer_resume(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_timers(void) {
|
||||||
|
timer_foreach(timer_default_config);
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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 "boards_private.h"
|
||||||
|
|
||||||
|
#include <libmaple/gpio.h>
|
||||||
|
#include <libmaple/timer.h>
|
||||||
|
|
||||||
|
#include <boards.h>
|
||||||
|
#include <usb_serial.h>
|
||||||
|
|
||||||
|
// Allow boards to provide a PLL multiplier. This is useful for
|
||||||
|
// e.g. STM32F100 value line MCUs, which use slower multipliers.
|
||||||
|
// (We're leaving the default to RCC_PLLMUL_9 for now, since that
|
||||||
|
// works for F103 performance line MCUs, which is all that LeafLabs
|
||||||
|
// currently officially supports).
|
||||||
|
#ifndef BOARD_RCC_PLLMUL
|
||||||
|
#define BOARD_RCC_PLLMUL RCC_PLLMUL_9
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace wirish {
|
||||||
|
namespace priv {
|
||||||
|
|
||||||
|
static stm32f1_rcc_pll_data pll_data = {BOARD_RCC_PLLMUL};
|
||||||
|
__weak rcc_pll_cfg w_board_pll_cfg = {RCC_PLLSRC_HSE, &pll_data};
|
||||||
|
__weak adc_prescaler w_adc_pre = ADC_PRE_PCLK2_DIV_6;
|
||||||
|
__weak adc_smp_rate w_adc_smp = ADC_SMPR_55_5;
|
||||||
|
|
||||||
|
__weak void board_reset_pll(void) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak void board_setup_gpio(void) {
|
||||||
|
gpio_init_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak void board_setup_usb(void) {
|
||||||
|
#if BOARD_HAVE_SERIALUSB
|
||||||
|
#ifdef BOOTLOADER_maple
|
||||||
|
// SerialUSB.begin();
|
||||||
|
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak void series_init(void) {
|
||||||
|
// Initialize AFIO here, too, so peripheral remaps and external
|
||||||
|
// interrupts work out of the box.
|
||||||
|
afio_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is a modified version of a file obtained from
|
||||||
|
* CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the
|
||||||
|
* following text appeared:
|
||||||
|
*
|
||||||
|
* The authors hereby grant permission to use, copy, modify, distribute,
|
||||||
|
* and license this software and its documentation for any purpose, provided
|
||||||
|
* that existing copyright notices are retained in all copies and that this
|
||||||
|
* notice is included verbatim in any distributions. No written agreement,
|
||||||
|
* license, or royalty fee is required for any of the authorized uses.
|
||||||
|
* Modifications to this software may be copyrighted by their authors
|
||||||
|
* and need not follow the licensing terms described here, provided that
|
||||||
|
* the new terms are clearly indicated on the first page of each file where
|
||||||
|
* they apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
|
||||||
|
.globl __start__
|
||||||
|
.type __start__, %function
|
||||||
|
__start__:
|
||||||
|
.fnstart
|
||||||
|
ldr r1,=__msp_init
|
||||||
|
mov sp,r1
|
||||||
|
ldr r1,=start_c
|
||||||
|
bx r1
|
||||||
|
.pool
|
||||||
|
.cantunwind
|
||||||
|
.fnend
|
|
@ -0,0 +1,95 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is a modified version of a file obtained from
|
||||||
|
* CodeSourcery Inc. (now part of Mentor Graphics Corp.), in which the
|
||||||
|
* following text appeared:
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006, 2007 CodeSourcery Inc
|
||||||
|
*
|
||||||
|
* The authors hereby grant permission to use, copy, modify, distribute,
|
||||||
|
* and license this software and its documentation for any purpose, provided
|
||||||
|
* that existing copyright notices are retained in all copies and that this
|
||||||
|
* notice is included verbatim in any distributions. No written agreement,
|
||||||
|
* license, or royalty fee is required for any of the authorized uses.
|
||||||
|
* Modifications to this software may be copyrighted by their authors
|
||||||
|
* and need not follow the licensing terms described here, provided that
|
||||||
|
* the new terms are clearly indicated on the first page of each file where
|
||||||
|
* they apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
extern void __libc_init_array(void);
|
||||||
|
|
||||||
|
extern int main(int, char**, char**);
|
||||||
|
|
||||||
|
extern void exit(int) __attribute__((noreturn, weak));
|
||||||
|
|
||||||
|
/* The linker must ensure that these are at least 4-byte aligned. */
|
||||||
|
extern char __data_start__, __data_end__;
|
||||||
|
extern char __bss_start__, __bss_end__;
|
||||||
|
|
||||||
|
struct rom_img_cfg {
|
||||||
|
int *img_start;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern char _lm_rom_img_cfgp;
|
||||||
|
|
||||||
|
void __attribute__((noreturn)) start_c(void) {
|
||||||
|
struct rom_img_cfg *img_cfg = (struct rom_img_cfg*)&_lm_rom_img_cfgp;
|
||||||
|
int *src = img_cfg->img_start;
|
||||||
|
int *dst = (int*)&__data_start__;
|
||||||
|
int exit_code;
|
||||||
|
|
||||||
|
/* Initialize .data, if necessary. */
|
||||||
|
if (src != dst) {
|
||||||
|
int *end = (int*)&__data_end__;
|
||||||
|
while (dst < end) {
|
||||||
|
*dst++ = *src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero .bss. */
|
||||||
|
dst = (int*)&__bss_start__;
|
||||||
|
while (dst < (int*)&__bss_end__) {
|
||||||
|
*dst++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run initializers. */
|
||||||
|
__libc_init_array();
|
||||||
|
|
||||||
|
/* Jump to main. */
|
||||||
|
exit_code = main(0, 0, 0);
|
||||||
|
if (exit) {
|
||||||
|
exit(exit_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If exit is NULL, make sure we don't return. */
|
||||||
|
for (;;)
|
||||||
|
continue;
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* The MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2010 Perry Hung.
|
||||||
|
* Copyright (c) 2011, 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/syscalls.c
|
||||||
|
* @brief newlib stubs
|
||||||
|
*
|
||||||
|
* Low level system routines used by newlib for basic I/O and memory
|
||||||
|
* allocation. You can override most of these.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libmaple/libmaple.h>
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* If CONFIG_HEAP_START (or CONFIG_HEAP_END) isn't defined, then
|
||||||
|
* assume _lm_heap_start (resp. _lm_heap_end) is appropriately set by
|
||||||
|
* the linker */
|
||||||
|
#ifndef CONFIG_HEAP_START
|
||||||
|
extern char _lm_heap_start;
|
||||||
|
#define CONFIG_HEAP_START ((void *)&_lm_heap_start)
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_HEAP_END
|
||||||
|
extern char _lm_heap_end;
|
||||||
|
#define CONFIG_HEAP_END ((void *)&_lm_heap_end)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _sbrk -- Increment the program break.
|
||||||
|
*
|
||||||
|
* Get incr bytes more RAM (for use by the heap). malloc() and
|
||||||
|
* friends call this function behind the scenes.
|
||||||
|
*/
|
||||||
|
void *_sbrk(int incr) {
|
||||||
|
static void * pbreak = NULL; /* current program break */
|
||||||
|
void * ret;
|
||||||
|
|
||||||
|
if (pbreak == NULL) {
|
||||||
|
pbreak = CONFIG_HEAP_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((CONFIG_HEAP_END - pbreak < incr) ||
|
||||||
|
(pbreak - CONFIG_HEAP_START < -incr)) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return (void *)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = pbreak;
|
||||||
|
pbreak += incr;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak int _open(const char *path, int flags, ...) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak int _close(int fd) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak int _fstat(int fd, struct stat *st) {
|
||||||
|
st->st_mode = S_IFCHR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak int _isatty(int fd) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak int isatty(int fd) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak int _lseek(int fd, off_t pos, int whence) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak unsigned char getch(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__weak int _read(int fd, char *buf, size_t cnt) {
|
||||||
|
*buf = getch();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak void putch(unsigned char c) {
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak void cgets(char *s, int bufsize) {
|
||||||
|
char *p;
|
||||||
|
int c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < bufsize; i++) {
|
||||||
|
*(s+i) = 0;
|
||||||
|
}
|
||||||
|
// memset(s, 0, bufsize);
|
||||||
|
|
||||||
|
p = s;
|
||||||
|
|
||||||
|
for (p = s; p < s + bufsize-1;) {
|
||||||
|
c = getch();
|
||||||
|
switch (c) {
|
||||||
|
case '\r' :
|
||||||
|
case '\n' :
|
||||||
|
putch('\r');
|
||||||
|
putch('\n');
|
||||||
|
*p = '\n';
|
||||||
|
return;
|
||||||
|
|
||||||
|
case '\b' :
|
||||||
|
if (p > s) {
|
||||||
|
*p-- = 0;
|
||||||
|
putch('\b');
|
||||||
|
putch(' ');
|
||||||
|
putch('\b');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
putch(c);
|
||||||
|
*p++ = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak int _write(int fd, const char *buf, size_t cnt) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < cnt; i++)
|
||||||
|
putch(buf[i]);
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override fgets() in newlib with a version that does line editing */
|
||||||
|
__weak char *fgets(char *s, int bufsize, void *f) {
|
||||||
|
cgets(s, bufsize);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
__weak void _exit(int exitcode) {
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
Loading…
Reference in New Issue