diff options
61 files changed, 2377 insertions, 2600 deletions
@@ -1,13 +1,11 @@ build/ docs/build/ +main.cpp libmaple.layout tags TAGS *~ *.swp docs/doxygen/ -<<<<<<< Updated upstream arm -======= -notes/ ->>>>>>> Stashed changes +cscope* @@ -9,17 +9,27 @@ VENDOR_ID := 1EAF PRODUCT_ID := 0003 # Guess the MCU based on the BOARD (can be overridden ) +# FIXME the error LED config needs to be in wirish/ instead ifeq ($(BOARD), maple) MCU := STM32F103RB PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOA_BASE + ERROR_LED_PIN := 5 + DENSITY := STM32_MEDIUM_DENSITY endif ifeq ($(BOARD), maple_native) MCU := STM32F103ZE PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOC_BASE + ERROR_LED_PIN := 15 + DENSITY := STM32_HIGH_DENSITY endif ifeq ($(BOARD), maple_mini) MCU := STM32F103CB PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOB_BASE + ERROR_LED_PIN := 1 + DENSITY := STM32_MEDIUM_DENSITY endif # Useful paths @@ -32,13 +42,26 @@ BUILD_PATH = build LIBMAPLE_PATH := $(SRCROOT)/libmaple SUPPORT_PATH := $(SRCROOT)/support -# Useful variables -GLOBAL_CFLAGS := -Os -g3 -gdwarf-2 -mcpu=cortex-m3 -mthumb -march=armv7-m -nostdlib \ - -ffunction-sections -fdata-sections -Wl,--gc-sections \ - -DBOARD_$(BOARD) -DMCU_$(MCU) -GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall -DBOARD_$(BOARD) -DMCU_$(MCU) -GLOBAL_ASFLAGS := -mcpu=cortex-m3 -march=armv7-m -mthumb -DBOARD_$(BOARD) \ - -DMCU_$(MCU) -x assembler-with-cpp +# Compilation flags. +# FIXME remove the ERROR_LED config +GLOBAL_CFLAGS := -Os -g3 -gdwarf-2 -mcpu=cortex-m3 -mthumb -march=armv7-m \ + -nostdlib \ + -ffunction-sections -fdata-sections -Wl,--gc-sections \ + -DBOARD_$(BOARD) -DMCU_$(MCU) \ + -DERROR_LED_PORT=$(ERROR_LED_PORT) \ + -DERROR_LED_PIN=$(ERROR_LED_PIN) \ + -D$(DENSITY) +GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall \ + -DBOARD_$(BOARD) -DMCU_$(MCU) \ + -DERROR_LED_PORT=$(ERROR_LED_PORT) \ + -DERROR_LED_PIN=$(ERROR_LED_PIN) \ + -D$(DENSITY) +GLOBAL_ASFLAGS := -mcpu=cortex-m3 -march=armv7-m -mthumb \ + -x assembler-with-cpp \ + -DBOARD_$(BOARD) -DMCU_$(MCU) \ + -DERROR_LED_PORT=$(ERROR_LED_PORT) \ + -DERROR_LED_PIN=$(ERROR_LED_PIN) \ + -D$(DENSITY) LDDIR := $(SUPPORT_PATH)/ld LDFLAGS = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR) \ diff --git a/build-targets.mk b/build-targets.mk index 0718b15..207d324 100644 --- a/build-targets.mk +++ b/build-targets.mk @@ -11,7 +11,7 @@ library: $(BUILD_PATH)/libmaple.a .PHONY: library $(BUILD_PATH)/$(BOARD).elf: $(BUILDDIRS) $(TGT_BIN) $(BUILD_PATH)/main.o - $(SILENT_LD) $(CXX) $(LDFLAGS) -o $@ $(TGT_BIN) $(BUILD_PATH)/main.o + $(SILENT_LD) $(CXX) $(LDFLAGS) -o $@ $(TGT_BIN) $(BUILD_PATH)/main.o -Wl,-Map,$(BUILD_PATH)/$(BOARD).map $(BUILD_PATH)/$(BOARD).bin: $(BUILD_PATH)/$(BOARD).elf $(SILENT_OBJCOPY) $(OBJCOPY) -v -Obinary $(BUILD_PATH)/$(BOARD).elf $@ 1>/dev/null diff --git a/docs/source/language.rst b/docs/source/language.rst index 2ebe03c..b2f4650 100644 --- a/docs/source/language.rst +++ b/docs/source/language.rst @@ -17,36 +17,6 @@ language and C++ may wish to skip to the .. contents:: Contents :local: -Unique Maple Additions ----------------------- - -.. _language-assert: - -``ASSERT(...)`` - The ``ASSERT()`` function can be very useful for basic program - debugging. The function accepts a boolean; for example:: - - ASSERT(state == WAIT); - - zero is false and any other number is true. If the boolean is true - the assertion passes and the program continues as usual. If it is - false, the assertion fails: the program is halted, debug - information is printed to USART2, and the status LED begins to - throb in intensity (it's noticeably different from blinking). The - debug information is printed at 9600 baud and consists of the - filename and line number where the particular assertion failed. - - Including assertions in a program increases the program size. When - using libmaple **from the command line only**, they can be - disabled by making the definition :: - - #define DEBUG_LEVEL DEBUG_NONE - - before including either wirish.h or libmaple.h. In this case, all - assertions will pass without any lost clock cycles. Note that - this will **not work in the IDE**; even with this definition, - assertions will still be enabled. - .. _language-lang-docs: Maple Language Reference @@ -217,6 +187,33 @@ A more exhaustive index is available at the :ref:`language-index`. | | | | +--------------------------------------------+----------------------------------------------+---------------------------------------------------+ +``ASSERT(...)`` +--------------- + +The ``ASSERT()`` function can be very useful for basic program +debugging. The function accepts a boolean; for example:: + + ASSERT(state == WAIT); + +Zero is false and any other number is true. If the boolean is true, the +assertion passes and the program continues as usual. If it is false, +the assertion fails: the program is halted, debug information is +printed to USART2, and the status LED begins to throb in intensity +(it's noticeably different from blinking). The debug information is +printed at 9600 baud and consists of the filename and line number +where the particular assertion failed. + +Including assertions in a program increases the program size. When +using libmaple **from the command line only**, they can be disabled by +making the definition :: + + #define DEBUG_LEVEL DEBUG_NONE + +before including either wirish.h or libmaple.h. In this case, all +assertions will pass without any lost clock cycles. Note that this +will **not work in the IDE**; even with this definition, assertions +will still be enabled. + .. _language-missing-features: Missing Arduino Features diff --git a/examples/test-bkp.cpp b/examples/test-bkp.cpp new file mode 100644 index 0000000..d0aa564 --- /dev/null +++ b/examples/test-bkp.cpp @@ -0,0 +1,80 @@ +#include <stdio.h> + +#include "wirish.h" +#include "bkp.h" +#include "iwdg.h" + +void print_bkp_contents(); +void write_to_bkp(uint16 val); + +#define comm Serial2 + +void setup() { + pinMode(BOARD_BUTTON_PIN, INPUT); + + comm.begin(9600); + comm.println("*** Beginning BKP test"); + + comm.println("Init..."); + bkp_init(); + comm.println("Done."); + + print_bkp_contents(); + write_to_bkp(10); + print_bkp_contents(); + + comm.println("Enabling backup writes."); + bkp_enable_writes(); + write_to_bkp(20); + print_bkp_contents(); + + comm.println("Disabling backup writes."); + bkp_disable_writes(); + write_to_bkp(30); + print_bkp_contents(); + + comm.println("Done testing backup registers; press button to enable " + "independent watchdog (in order to cause a reset)."); + waitForButtonPress(0); + iwdg_init(IWDG_PRE_4, 1); + comm.println(); +} + +void loop() { +} + +void print_bkp_contents() { + comm.println("Backup data register contents:"); + char buf[100]; + for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { + snprintf(buf, sizeof buf, "DR%d: %d ", i, bkp_read(i)); + comm.print(buf); + if (i % 5 == 0) comm.println(); + } + comm.println(); +} + +void write_to_bkp(uint16 val) { + comm.print("Attempting to write "); + comm.print(val); + comm.println(" to backup registers..."); + for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { + bkp_write(i, val); + } + comm.println("Done."); +} + +__attribute__((constructor)) void premain() { + init(); +} + +int main(void) { + init(); + setup(); + + while (1) { + loop(); + } + return 0; +} + diff --git a/examples/test-dac.cpp b/examples/test-dac.cpp index 3a699e2..62f40eb 100644 --- a/examples/test-dac.cpp +++ b/examples/test-dac.cpp @@ -16,7 +16,7 @@ void setup() { Serial1.println("**** Beginning DAC test");
Serial1.print("Init... ");
- dac_init();
+ dac_init(DAC_CH1 | DAC_CH2);
Serial1.println("Done.");
}
@@ -29,8 +29,8 @@ void loop() { count = 0;
}
- dac_write(1, 2048);
- dac_write(2, count);
+ dac_write_channel(1, 4095 - count);
+ dac_write_channel(2, count);
}
int main(void) {
diff --git a/examples/test-session.cpp b/examples/test-session.cpp index 845547d..72d64d6 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -512,7 +512,7 @@ void cmd_sequential_gpio_writes(void) { // make sure to skip the TX/RX headers for(uint32 i = 2; i<NR_GPIO_PINS; i++) { COMM.print("GPIO write out on header D"); - COMM.print(i, DEC); + COMM.print((int)i, DEC); COMM.println("..."); pinMode(i, OUTPUT); do { @@ -614,9 +614,8 @@ void init_all_timers(uint16 prescale) { timer_init(TIMER1, prescale); timer_init(TIMER2, prescale); timer_init(TIMER3, prescale); -#if NR_TIMERS >= 4 timer_init(TIMER4, prescale); -#elif NR_TIMERS >= 8 // TODO test this on maple native +#ifdef STM32_HIGH_DENSITY timer_init(TIMER5, prescale); timer_init(TIMER6, prescale); timer_init(TIMER7, prescale); diff --git a/libmaple/adc.c b/libmaple/adc.c index 3e6818c..cd71118 100644 --- a/libmaple/adc.c +++ b/libmaple/adc.c @@ -24,84 +24,88 @@ /** * @brief Analog to digital converter routines + * + * IMPORTANT: maximum external impedance must be below 0.4kOhms for 1.5 + * sample conversion time. + * + * At 55.5 cycles/sample, the external input impedance < 50kOhms. + * + * See stm32 manual RM008 for how to calculate this. */ #include "libmaple.h" #include "rcc.h" #include "adc.h" -/* The ADC input clock is generated from PCLK2/APB2 divided by a prescaler - * and it must not exceed 14MHz. - * - * ADC1 and ADC2 are clocked by APB2 - * - * 1) Power on by setting ADON in ADC_CR2 - * Conversion starts when ADON is set for a second time after some - * time t > t_stab. - * - * Up to 16 selected conversion must be selected in ADC_SQRx - * - * Single conversion mode: - * Set the ADON bit in the ADC_CR2 register - * Once the conversion is complete: - * Converted data is stored in ADC_DR - * EOC flag is set - * Interrupt is generated if EOCIE is set - * - * Calibration: - * Calibration is started by setting the CAL bit in the ADC_CR2 register. - * Once calibration is over, the CAL bit is reset by hardware and normal - * conversion can be performed. Calibrate at power-on. - * - * ALIGN in ADC_CR2 selects the alignment of data - * - * IMPORTANT: maximum external impedance must be below 0.4kOhms for 1.5 - * sample conversion time. - * - * At 55.5 cycles/sample, the external input impedance < 50kOhms*/ +adc_dev adc1 = { + .regs = ADC1_BASE, + .clk_id = RCC_ADC1 +}; +const adc_dev *ADC1 = &adc1; -void set_adc_smprx(adc_smp_rate smp_rate); +adc_dev adc2 = { + .regs = ADC2_BASE, + .clk_id = RCC_ADC2 +}; +const adc_dev *ADC2 = &adc2; -void adc_init(adc_smp_rate smp_rate) { - rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6); - rcc_clk_enable(RCC_ADC1); - rcc_reset_dev(RCC_ADC1); +#ifdef STM32_HIGH_DENSITY +adc_dev adc3 = { + .regs = ADC3_BASE, + .clk_id = RCC_ADC3 +}; +const adc_dev *ADC3 = &adc3; +#endif - ADC_CR1 = 0; - /* Software triggers conversions */ - ADC_CR2 = CR2_EXTSEL_SWSTART | CR2_EXTTRIG; - ADC_SQR1 = 0; +static void adc_calibrate(const adc_dev *dev); - /* Set the sample conversion time. See note above for impedance - requirements. */ - adc_set_sample_rate(smp_rate); +/** + * @brief Initialize an ADC peripheral. Only supports software triggered + * conversions. + * @param dev ADC peripheral to initialize + * @param flags unused + */ +void adc_init(const adc_dev *dev, uint32 flags) { + /* Spin up the clocks */ + rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6); + rcc_clk_enable(dev->clk_id); + rcc_reset_dev(dev->clk_id); - /* Enable the ADC */ - CR2_ADON_BIT = 1; + /* Software triggers conversions, conversion on external events */ + adc_set_extsel(dev, 7); + adc_set_exttrig(dev, 1); - /* Reset the calibration registers and then perform a reset */ - CR2_RSTCAL_BIT = 1; - while(CR2_RSTCAL_BIT) - ; + /* Enable the ADC */ + adc_enable(dev); - CR2_CAL_BIT = 1; - while(CR2_CAL_BIT) - ; + /* Calibrate ADC */ + adc_calibrate(dev); } - -void adc_disable(void) { - CR2_ADON_BIT = 0; +/** + * @brief Set external event select for regular group + * @param dev adc device + * @param trigger event to select. See ADC_CR2 EXTSEL[2:0] bits. + */ +void adc_set_extsel(const adc_dev *dev, uint8 trigger) { + uint32 cr2 = dev->regs->CR2; + cr2 &= ~ADC_CR2_EXTSEL; + cr2 |= (trigger & 0x7) << 17; + dev->regs->CR2 = cr2; } -/* Turn the given sample rate into values for ADC_SMPRx. (Don't - * precompute in order to avoid wasting space). - * - * Don't call this during conversion! + +/** + * @brief Turn the given sample rate into values for ADC_SMPRx. Don't + * call this during conversion. + * @param dev adc device + * @param smp_rate sample rate to set + * @see adc_smp_rate */ -void adc_set_sample_rate(adc_smp_rate smp_rate) { +void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) { uint32 adc_smpr1_val = 0, adc_smpr2_val = 0; int i; + for (i = 0; i < 10; i++) { if (i < 8) { /* ADC_SMPR1 determines sample time for channels [10,17] */ @@ -110,6 +114,24 @@ void adc_set_sample_rate(adc_smp_rate smp_rate) { /* ADC_SMPR2 determines sample time for channels [0,9] */ adc_smpr2_val |= smp_rate << (i * 3); } - ADC_SMPR1 = adc_smpr1_val; - ADC_SMPR2 = adc_smpr2_val; + + dev->regs->SMPR1 = adc_smpr1_val; + dev->regs->SMPR2 = adc_smpr2_val; +} + +/** + * @brief Calibrate an ADC peripheral + * @param dev adc device + */ +static void adc_calibrate(const adc_dev *dev) { + __io uint32 *rstcal_bit = (__io uint32*)BITBAND_PERI(&(dev->regs->CR2), 3); + __io uint32 *cal_bit = (__io uint32*)BITBAND_PERI(&(dev->regs->CR2), 2); + + *rstcal_bit = 1; + while (*rstcal_bit) + ; + + *cal_bit = 1; + while (*cal_bit) + ; } diff --git a/libmaple/adc.h b/libmaple/adc.h index 976986f..ac386fb 100644 --- a/libmaple/adc.h +++ b/libmaple/adc.h @@ -25,87 +25,174 @@ /** * @file adc.h * - * @brief Analog-to-Digital Conversion (ADC) routines. + * @brief Analog-to-Digital Conversion (ADC) header. */ #ifndef _ADC_H_ #define _ADC_H_ #include "util.h" +#include "rcc.h" + #ifdef __cplusplus extern "C"{ #endif -/* Notes: - * The maximum input impedance on each channel MUST be below .4kohms, - * or face the wrath of incorrect readings... - * This can be changed at the expense of sample time... see datasheet - * - * Need to up the sample time if otherwise... see datasheet */ - -/* TODO: We'll only use ADC1 for now. See page 41 of the manual for - ADC2 and ADC3's real addresses. */ -#define ADC1_BASE 0x40012400 -#define ADC2_BASE 0x40012400 -#define ADC3_BASE 0x40012400 - -#define ADC_SR *(volatile uint32*)(ADC1_BASE + 0) -#define ADC_CR1 *(volatile uint32*)(ADC1_BASE + 0x4) -#define ADC_CR2 *(volatile uint32*)(ADC1_BASE + 0x8) -#define ADC_SMPR1 *(volatile uint32*)(ADC1_BASE + 0xC) -#define ADC_SMPR2 *(volatile uint32*)(ADC1_BASE + 0x10) -#define ADC_SQR1 *(volatile uint32*)(ADC1_BASE + 0x2C) -#define ADC_SQR3 *(volatile uint32*)(ADC1_BASE + 0x34) -#define ADC_DR *(volatile uint32*)(ADC1_BASE + 0x4C) - -#define CR2_EXTSEL_SWSTART (0xE << 16) -#define CR2_RSTCAL (BIT(3)) -#define CR2_EXTTRIG (BIT(20)) - -/* Bit banded bits */ -#define CR2_ADON_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 0)) -#define CR2_CAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 2)) -#define CR2_RSTCAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 3)) -#define CR2_SWSTART_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 22)) -#define SR_EOC_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0, 1)) -/* (NR_ANALOG_PINS is board specific) */ +typedef struct adc_reg_map { + __io uint32 SR; ///< Status register + __io uint32 CR1; ///< Control register 1 + __io uint32 CR2; ///< Control register 2 + __io uint32 SMPR1; ///< Sample time register 1 + __io uint32 SMPR2; ///< Sample time register 2 + __io uint32 JOFR1; ///< Injected channel data offset register 1 + __io uint32 JOFR2; ///< Injected channel data offset register 2 + __io uint32 JOFR3; ///< Injected channel data offset register 3 + __io uint32 JOFR4; ///< Injected channel data offset register 4 + __io uint32 HTR; ///< Watchdog high threshold register + __io uint32 LTR; ///< Watchdog low threshold register + __io uint32 SQR1; ///< Regular sequence register 1 + __io uint32 SQR2; ///< Regular sequence register 2 + __io uint32 SQR3; ///< Regular sequence register 3 + __io uint32 JSQR; ///< Injected sequence register + __io uint32 JDR1; ///< Injected data register 1 + __io uint32 JDR2; ///< Injected data register 2 + __io uint32 JDR3; ///< Injected data register 3 + __io uint32 JDR4; ///< Injected data register 4 + __io uint32 DR; ///< Regular data register +} adc_reg_map; + +typedef struct adc_dev { + adc_reg_map *regs; + rcc_clk_id clk_id; +} adc_dev; + +extern const adc_dev *ADC1; +extern const adc_dev *ADC2; +#ifdef STM32_HIGH_DENSITY +extern const adc_dev *ADC3; +#endif + +/* + * ADC peripheral base addresses + */ +#define ADC1_BASE ((adc_reg_map*)0x40012400) +#define ADC2_BASE ((adc_reg_map*)0x40012800) +#define ADC3_BASE ((adc_reg_map*)0x40013C00) + +/* + * Register bit definitions + */ + +/* Status register */ +#define ADC_SR_AWD BIT(0) +#define ADC_SR_EOC BIT(1) +#define ADC_SR_JEOC BIT(2) +#define ADC_SR_JSTRT BIT(3) +#define ADC_SR_STRT BIT(4) + +/* Control register 1 */ +#define ADC_CR1_AWDCH (0x1F) +#define ADC_CR1_EOCIE BIT(5) +#define ADC_CR1_AWDIE BIT(6) +#define ADC_CR1_JEOCIE BIT(7) +#define ADC_CR1_SCAN BIT(8) +#define ADC_CR1_AWDSGL BIT(9) +#define ADC_CR1_JAUTO BIT(10) +#define ADC_CR1_DISCEN BIT(11) +#define ADC_CR1_JDISCEN BIT(12) +#define ADC_CR1_DISCNUM (0xE000) +#define ADC_CR1_JAWDEN BIT(22) +#define ADC_CR1_AWDEN BIT(23) + +/* Control register 2 */ +#define ADC_CR2_ADON BIT(0) +#define ADC_CR2_CONT BIT(1) +#define ADC_CR2_CAL BIT(2) +#define ADC_CR2_RSTCAL BIT(3) +#define ADC_CR2_DMA BIT(8) +#define ADC_CR2_ALIGN BIT(11) +#define ADC_CR2_JEXTSEL (0x7000) +#define ADC_CR2_JEXTTRIG BIT(15) +#define ADC_CR2_EXTSEL (0xE0000) +#define ADC_CR2_EXTTRIG BIT(20) +#define ADC_CR2_JSWSTART BIT(21) +#define ADC_CR2_SWSTART BIT(22) +#define ADC_CR2_TSEREFE BIT(23) + +void adc_init(const adc_dev *dev, uint32 flags); +void adc_set_extsel(const adc_dev *dev, uint8 trigger); /** ADC per-sample conversion times, in ADC clock cycles */ typedef enum { - ADC_SMPR_1_5, - ADC_SMPR_7_5, - ADC_SMPR_13_5, - ADC_SMPR_28_5, - ADC_SMPR_41_5, - ADC_SMPR_55_5, - ADC_SMPR_71_5, - ADC_SMPR_239_5 + ADC_SMPR_1_5, ///< 1.5 ADC cycles + ADC_SMPR_7_5, ///< 7.5 ADC cycles + ADC_SMPR_13_5, ///< 13.5 ADC cycles + ADC_SMPR_28_5, ///< 28.5 ADC cycles + ADC_SMPR_41_5, ///< 41.5 ADC cycles + ADC_SMPR_55_5, ///< 55.5 ADC cycles + ADC_SMPR_71_5, ///< 71.5 ADC cycles + ADC_SMPR_239_5 ///< 239.5 ADC cycles } adc_smp_rate; -/** Initialize ADC1 to do one-shot conversions at the given sample - rate. */ -void adc_init(adc_smp_rate smp_rate); - -void adc_set_sample_rate(adc_smp_rate smp_rate); - -void adc_disable(void); +void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); /** - * Perform a single conversion on ADC[0-15]. - * PRECONDITIONS: - * adc initialized */ -static inline int adc_read(int channel) { - /* Set channel */ - ADC_SQR3 = channel; + * @brief Perform a single synchronous software triggered conversion on a + * channel + * @param regs ADC register map + * @param channel channel to convert + * @return conversion result + */ +static inline uint32 adc_read(const adc_dev *dev, uint8 channel) { + adc_reg_map *regs = dev->regs; + + /* Set target channel */ + regs->SQR3 = channel; /* Start the conversion */ - CR2_SWSTART_BIT = 1; + regs->CR2 |= ADC_CR2_SWSTART; /* Wait for it to finish */ - while(SR_EOC_BIT == 0) + while((regs->SR & ADC_SR_EOC) == 0) ; - return ADC_DR; + return regs->DR; +} + +/** + * @brief Set external trigger conversion mode event for regular channels + * @param dev adc device + * @param enable if 1, conversion on external events is enabled, 0 to disable + */ +static inline void adc_set_exttrig(const adc_dev *dev, uint8 enable) { + __write(BITBAND_PERI(&(dev->regs->CR2), 20), enable); +} + +/** + * @brief Enable an adc peripheral + * @param regs register map of peripheral to enable + */ +static inline void adc_enable(const adc_dev *dev) { + __write(BITBAND_PERI(&(dev->regs->CR2), 0), 1); +} + +/** + * @brief Disable an adc peripheral + * @param regs register map of peripheral to disable + */ +static inline void adc_disable(const adc_dev *dev) { + __write(BITBAND_PERI(&(dev->regs->CR2), 0), 0); +} + +/** + * @brief Disable all ADCs + */ +static inline void adc_disable_all(void) { + adc_disable(ADC1); + adc_disable(ADC2); +#ifdef STM32_HIGH_DENSITY + adc_disable(ADC3); +#endif } #ifdef __cplusplus diff --git a/libmaple/bkp.c b/libmaple/bkp.c index e89abd0..ed107d8 100644 --- a/libmaple/bkp.c +++ b/libmaple/bkp.c @@ -24,63 +24,101 @@ * SOFTWARE. *****************************************************************************/ -#include "libmaple.h" #include "bkp.h" #include "pwr.h" #include "rcc.h" #include "util.h" -/* Data register memory layout is not contiguous. It's split up from - 1--NR_LOW_DRS, beginning at BKP_LOW_OFFSET, through - (NR_LOW_DRS+1)--NR_DRS, beginning at BKP_HIGH_OFFSET. */ -#define NR_LOW_DRS 10 -#define BKP_LOW_OFFSET 0x4 /* start offset for data registers 1--10 */ -#define BKP_HIGH_OFFSET 0x40 /* start offset for data registers 11--42 */ +static inline __io uint32* data_register(uint8 reg); -inline volatile uint16* reg_addr(uint8 reg) { - if (1 <= reg) { - if (reg <= NR_LOW_DRS) { - return (volatile uint16*)(BKP_BASE + BKP_LOW_OFFSET + - (reg - 1) * 4); - } else if (reg <= NR_BKP_REGS) { - return (volatile uint16*)(BKP_BASE + BKP_HIGH_OFFSET + - (reg - NR_LOW_DRS - 1) * 4); - } - } - return 0; -} +bkp_dev bkp = { + .regs = BKP_BASE, +}; -void bkp_init(void) { - /* Set PWREN (28) and BKPEN (27) bits */ - __set_bits(RCC_APB1ENR, BIT(28) | BIT(27)); -} +const bkp_dev *BKP = &bkp; -void bkp_disable(void) { - __clear_bits(RCC_APB1ENR, BIT(28) | BIT(27)); +/** + * @brief Initialize backup interface. + * + * Enables the power and backup interface clocks, and resets the + * backup device. + */ +void bkp_init(void) { + /* Don't call pwr_init(), or you'll reset the device. We just + * need the clock. */ + rcc_clk_enable(RCC_PWR); + rcc_clk_enable(RCC_BKP); + rcc_reset_dev(RCC_BKP); } +/** + * Enable write access to the backup registers. Backup interface must + * be initialized for subsequent register writes to work. + * @see bkp_init() + */ void bkp_enable_writes(void) { - /* Set the DBP bit in PWR_CR */ - __write(BITBAND_PERI(PWR_CR, PWR_CR_DBP), 1); + __write(BITBAND_PERI(&(PWR_BASE->CR), PWR_CR_DBP), 1); } +/** + * Disable write access to the backup registers. + */ void bkp_disable_writes(void) { - __write(BITBAND_PERI(PWR_CR, PWR_CR_DBP), 0); + __write(BITBAND_PERI(&(PWR_BASE->CR), PWR_CR_DBP), 0); } +/** + * Read a value from given backup data register. + * @param reg Data register to read, from 1 to BKP_NR_DATA_REGS (10 on + * medium-density devices, 42 on high-density devices). + */ uint16 bkp_read(uint8 reg) { - volatile uint16* addr = reg_addr(reg); - if (addr != 0) { - return *addr; + __io uint32* dr = data_register(reg); + if (!dr) { + ASSERT(0); /* nonexistent register */ + return 0; } - ASSERT(0); /* nonexistent register */ - return 0; + return (uint16)*dr; } +/** + * @brief Write a value to given data register. + * + * Write access to backup registers must be enabled. + * + * @param reg Data register to write, from 1 to BKP_NR_DATA_REGS (10 + * on medium-density devices, 42 on high-density devices). + * @param val Value to write into the register. + * @see bkp_enable_writes() + */ void bkp_write(uint8 reg, uint16 val) { - volatile uint16* addr = reg_addr(reg); - if (addr != 0) { - *addr = val; + __io uint32* dr = data_register(reg); + if (!dr) { + ASSERT(0); /* nonexistent register */ + return; + } + *dr = (uint32)val; +} + +/* + * Data register memory layout is not contiguous. It's split up from + * 1--NR_LOW_DRS, beginning at BKP_BASE->DR1, through to + * (NR_LOW_DRS+1)--BKP_NR_DATA_REGS, beginning at BKP_BASE->DR11. + */ +#define NR_LOW_DRS 10 + +static inline __io uint32* data_register(uint8 reg) { + if (reg < 1 || reg > BKP_NR_DATA_REGS) { + return 0; + } + +#if BKP_NR_DATA_REGS == NR_LOW_DRS + return (uint32*)BKP_BASE + reg; +#else + if (reg <= NR_LOW_DRS) { + return (uint32*)BKP_BASE + reg; + } else { + return (uint32*)&(BKP_BASE->DR11) + (reg - NR_LOW_DRS - 1); } - ASSERT(0); /* nonexistent register */ +#endif } diff --git a/libmaple/bkp.h b/libmaple/bkp.h index 9ad4c41..96ef8d2 100644 --- a/libmaple/bkp.h +++ b/libmaple/bkp.h @@ -32,51 +32,89 @@ #ifndef _BKP_H_ #define _BKP_H_ +#include "libmaple.h" + #ifdef __cplusplus extern "C" { #endif -#define BKP_BASE 0x40006C00 -#define BKP_RTCCR (BKP_BASE + 0x2C) -#define BKP_CR (BKP_BASE + 0x30) -#define BKP_CSR (BKP_BASE + 0x34) +#if defined(STM32_MEDIUM_DENSITY) +#define BKP_NR_DATA_REGS 10 +#elif defined(STM32_HIGH_DENSITY) +#define BKP_NR_DATA_REGS 42 +#endif -/** - * Initialize backup interface. This function enables the power and - * backup interface clocks. It does not enable write access to the - * backup registers. - */ -void bkp_init(void); +typedef struct bkp_reg_map { + const uint32 RESERVED1; + __io uint32 DR1; ///< Data register 1 + __io uint32 DR2; ///< Data register 2 + __io uint32 DR3; ///< Data register 3 + __io uint32 DR4; ///< Data register 4 + __io uint32 DR5; ///< Data register 5 + __io uint32 DR6; ///< Data register 6 + __io uint32 DR7; ///< Data register 7 + __io uint32 DR8; ///< Data register 8 + __io uint32 DR9; ///< Data register 9 + __io uint32 DR10; ///< Data register 10 + __io uint32 RTCCR; ///< RTC control register + __io uint32 CR; ///< Control register + __io uint32 CSR; ///< Control and status register +#ifdef STM32_HIGH_DENSITY + const uint32 RESERVED2; + const uint32 RESERVED3; + __io uint32 DR11; ///< Data register 11 + __io uint32 DR12; ///< Data register 12 + __io uint32 DR13; ///< Data register 13 + __io uint32 DR14; ///< Data register 14 + __io uint32 DR15; ///< Data register 15 + __io uint32 DR16; ///< Data register 16 + __io uint32 DR17; ///< Data register 17 + __io uint32 DR18; ///< Data register 18 + __io uint32 DR19; ///< Data register 19 + __io uint32 DR20; ///< Data register 20 + __io uint32 DR21; ///< Data register 21 + __io uint32 DR22; ///< Data register 22 + __io uint32 DR23; ///< Data register 23 + __io uint32 DR24; ///< Data register 24 + __io uint32 DR25; ///< Data register 25 + __io uint32 DR26; ///< Data register 26 + __io uint32 DR27; ///< Data register 27 + __io uint32 DR28; ///< Data register 28 + __io uint32 DR29; ///< Data register 29 + __io uint32 DR30; ///< Data register 30 + __io uint32 DR31; ///< Data register 31 + __io uint32 DR32; ///< Data register 32 + __io uint32 DR33; ///< Data register 33 + __io uint32 DR34; ///< Data register 34 + __io uint32 DR35; ///< Data register 35 + __io uint32 DR36; ///< Data register 36 + __io uint32 DR37; ///< Data register 37 + __io uint32 DR38; ///< Data register 38 + __io uint32 DR39; ///< Data register 39 + __io uint32 DR40; ///< Data register 40 + __io uint32 DR41; ///< Data register 41 + __io uint32 DR42; ///< Data register 42 +#endif +} bkp_reg_map; -/** Disable power and backup interface clocks. */ -void bkp_disable(void); +typedef struct bkp_dev { + bkp_reg_map *regs; +} bkp_dev; /** - * Enable write access to the backup registers. Backup interface must - * be initialized for subsequent register writes to work. - * @see bkp_init() + * Backup device. */ -void bkp_enable_writes(void); +extern const bkp_dev *BKP; -/** - * Disable write access to the backup registers. Does not disable - * backup interface clocks. +/* + * Backup peripheral base. */ -void bkp_disable_writes(void); +#define BKP_BASE ((bkp_reg_map*)0x40006C00) -/** - * Read a value from given backup data register. - * @param reg Data register to read, from 1 to NR_BKP_REGS (10 on Maple). - */ +void bkp_init(void); +void bkp_enable_writes(void); +void bkp_disable_writes(void); uint16 bkp_read(uint8 reg); - -/** - * Write a value to given data register. Backup interface must have - * been previously initialized, and write access to backup registers - * must be enabled. - * @param reg Data register to write, from 1 to NR_BKP_REGS (10 on Maple). - * @param val Value to write into the register. - */ void bkp_write(uint8 reg, uint16 val); #ifdef __cplusplus diff --git a/libmaple/dac.c b/libmaple/dac.c index 63a96ac..54b555b 100644 --- a/libmaple/dac.c +++ b/libmaple/dac.c @@ -23,7 +23,6 @@ *****************************************************************************/ #include "libmaple.h" -#include "rcc.h" #include "gpio.h" #include "dac.h" @@ -31,35 +30,81 @@ * @brief DAC peripheral routines. */ -/* This numbering follows the registers (1-indexed) */ -#define DAC_CH1 1 -#define DAC_CH2 2 +dac_dev dac = { + .regs = DAC_BASE, +}; +const dac_dev *DAC = &dac; -DAC_Map *dac = (DAC_Map*)(DAC_BASE); - -/* Sets up the DAC peripheral */ -void dac_init(void) { +/** + * @brief Initialize the digital to analog converter + * @param flags Flags: + * DAC_CH1: Enable channel 1 + * DAC_CH2: Enable channel 2 + * @sideeffect May set PA4 or PA5 to INPUT_ANALOG + */ +void dac_init(uint32 flags) { /* First turn on the clock */ rcc_clk_enable(RCC_DAC); + rcc_reset_dev(RCC_DAC); - /* Then setup ANALOG mode on PA4 and PA5 */ - gpio_set_mode(GPIOA_BASE, 4, CNF_INPUT_ANALOG); - gpio_set_mode(GPIOA_BASE, 5, CNF_INPUT_ANALOG); + if (flags & DAC_CH1) { + dac_enable_channel(1); + } - /* Then do register stuff. Default does no triggering, and - * buffered output, so all good. */ - dac->CR = DAC_CR_EN1 | DAC_CR_EN2; + if (flags & DAC_CH2) { + dac_enable_channel(2); + } } -void dac_write(uint8 chan, uint16 val) { - switch(chan) { - case DAC_CH1: - dac->DHR12R1 = 0x0FFF & val; +/** + * @brief Write a 12-bit value to the DAC to output + * @param channel channel to select (1 or 2) + * @param val value to write + */ +void dac_write_channel(uint8 channel, uint16 val) { + switch(channel) { + case 1: + DAC->regs->DHR12R1 = DAC_DHR12R1_DACC1DHR & val; + break; + case 2: + DAC->regs->DHR12R2 = DAC_DHR12R2_DACC2DHR & val; + break; + } +} + +/** + * @brief Enable a DAC channel + * @param channel channel to enable, either 1 or 2 + * @sideeffect May change pin mode of PA4 or PA5 + */ +void dac_enable_channel(uint8 channel) { + /* + * Setup ANALOG mode on PA4 and PA5. This mapping is consistent across + * all STM32 chips with a DAC. See RM008 12.2. + */ + switch (channel) { + case 1: + gpio_set_mode(GPIOA_BASE, 4, GPIO_MODE_INPUT_ANALOG); + DAC->regs->CR |= DAC_CR_EN1; + break; + case 2: + gpio_set_mode(GPIOA_BASE, 5, GPIO_MODE_INPUT_ANALOG); + DAC->regs->CR |= DAC_CR_EN2; + break; + } +} + +/** + * @brief Disable a DAC channel + * @param channel channel to disable, either 1 or 2 + */ +void dac_disable_channel(uint8 channel) { + switch (channel) { + case 1: + DAC->regs->CR &= ~DAC_CR_EN1; break; - case DAC_CH2: - dac->DHR12R2 = 0x0FFF & val; + case 2: + DAC->regs->CR &= ~DAC_CR_EN2; break; - default: - ASSERT(0); // can't happen } } diff --git a/libmaple/dac.h b/libmaple/dac.h index 340a49a..bc64324 100644 --- a/libmaple/dac.h +++ b/libmaple/dac.h @@ -22,92 +22,131 @@ * THE SOFTWARE. *****************************************************************************/ -/* - * See ../notes/dac.txt for more info - */ - /** * @file dac.h + * @brief Digital to analog converter header file + * See notes/dac.txt for more info */ #ifndef _DAC_H_ #define _DAC_H_ +#include "rcc.h" + #ifdef __cplusplus extern "C"{ #endif -#define DAC_BASE 0x40007400 - -typedef struct { - volatile uint32 CR; - volatile uint32 SWTRIGR; - volatile uint32 DHR12R1; - volatile uint32 DHR12L1; - volatile uint32 DHR8R1; - volatile uint32 DHR12R2; - volatile uint32 DHR12L2; - volatile uint32 DHR8R2; - volatile uint32 DHR12RD; - volatile uint32 DHR12LD; - volatile uint32 DHR8RD; - volatile uint32 DOR1; - volatile uint32 DOR2; -} DAC_Map; - -/* There's only one DAC, so expose it. */ -extern DAC_Map *dac; - -// And here are the register bit ranges -#define DAC_CR_EN1 BIT(0) -#define DAC_CR_BOFF1 BIT(1) -#define DAC_CR_TEN1 BIT(2) -#define DAC_CR_TSEL1 (BIT(3) | BIT(4) | BIT(5)) -#define DAC_CR_WAVE1 (BIT(6) | BIT(7)) -#define DAC_CR_MAMP1 (BIT(8) | BIT(9) | BIT(10) | BIT(11)) -#define DAC_CR_DMAEN1 BIT(12) -#define DAC_CR_EN2 BIT(16) -#define DAC_CR_BOFF2 BIT(17) -#define DAC_CR_TEN2 BIT(18) -#define DAC_CR_TSEL2 (BIT(19) | BIT(20) | BIT(21)) -#define DAC_CR_WAVE2 (BIT(22) | BIT(23)) -#define DAC_CR_MAMP2 (BIT(24) | BIT(25) | BIT(26) | BIT(27)) -#define DAC_CR_DMAEN2 BIT(28) - -#define DAC_SWTRIGR_SWTRIG1 BIT(0) -#define DAC_SWTRIGR_SWTRIG2 BIT(1) +/** DAC register map. */ +typedef struct dac_reg_map { + __io uint32 CR; /**< Control register */ + __io uint32 SWTRIGR; /**< Software trigger register */ + __io uint32 DHR12R1; /**< Channel 1 12-bit right-aligned data + holding register */ + __io uint32 DHR12L1; /**< Channel 1 12-bit left-aligned data + holding register */ + __io uint32 DHR8R1; /**< Channel 1 8-bit left-aligned data + holding register */ + __io uint32 DHR12R2; /**< Channel 2 12-bit right-aligned data + holding register */ + __io uint32 DHR12L2; /**< Channel 2 12-bit left-aligned data + holding register */ + __io uint32 DHR8R2; /**< Channel 2 8-bit left-aligned data + holding register */ + __io uint32 DHR12RD; /**< Dual DAC 12-bit right-aligned data + holding register */ + __io uint32 DHR12LD; /**< Dual DAC 12-bit left-aligned data + holding register */ + __io uint32 DHR8RD; /**< Dual DAC 8-bit left-aligned data holding + register */ + __io uint32 DOR1; /**< Channel 1 data output register */ + __io uint32 DOR2; /**< Channel 2 data output register */ +} dac_reg_map; + +typedef struct dac_dev { + dac_reg_map *regs; +} dac_dev; + +/** DAC device. */ +extern const dac_dev *DAC; + +/* + * DAC peripheral base address + */ +#define DAC_BASE ((dac_reg_map*)0x40007400) + +/* + * Register bit definitions and masks + */ +/* Control register */ +/* Channel 1 control */ +#define DAC_CR_EN1 BIT(0) /* Enable */ +#define DAC_CR_BOFF1 BIT(1) /* Output buffer disable */ +#define DAC_CR_TEN1 BIT(2) /* Trigger enable */ +#define DAC_CR_TSEL1 (0x7 << 3) /* Trigger selection */ +#define DAC_CR_WAVE1 (0x3 << 6) /* Noise/triangle wave enable */ +#define DAC_CR_MAMP1 (0xF << 8) /* Mask/amplitude selector */ +#define DAC_CR_DMAEN1 BIT(12) /* DMA enable */ +/* Channel 2 control */ +#define DAC_CR_EN2 BIT(16) /* Enable */ +#define DAC_CR_BOFF2 BIT(17) /* Output buffer disable */ +#define DAC_CR_TEN2 BIT(18) /* Trigger enable */ +#define DAC_CR_TSEL2 (0x7 << 19) /* Trigger selection */ +#define DAC_CR_WAVE2 (0x3 << 22) /* Noise/triangle wave generation*/ +#define DAC_CR_MAMP2 (0xF << 24) /* Mask/amplitude selector */ +#define DAC_CR_DMAEN2 BIT(28) /* DMA enable */ + +/* Software trigger register */ +#define DAC_SWTRIGR_SWTRIG1 BIT(0) /* Channel 1 software trigger */ +#define DAC_SWTRIGR_SWTRIG2 BIT(1) /* Channel 2 software trigger */ + +/* Channel 1 12-bit right-aligned data holding register */ #define DAC_DHR12R1_DACC1DHR 0x00000FFF +/* Channel 1 12-bit left-aligned data holding register */ #define DAC_DHR12L1_DACC1DHR 0x0000FFF0 +/* Channel 1 8-bit left-aligned data holding register */ #define DAC_DHR8R1_DACC1DHR 0x000000FF +/* Channel 2 12-bit right-aligned data holding register */ #define DAC_DHR12R2_DACC2DHR 0x00000FFF +/* Channel 2 12-bit left-aligned data holding register */ #define DAC_DHR12L2_DACC2DHR 0x0000FFF0 +/* Channel 2 8-bit left-aligned data holding register */ #define DAC_DHR8R2_DACC2DHR 0x000000FF +/* Dual DAC 12-bit right-aligned data holding register */ #define DAC_DHR12RD_DACC1DHR 0x00000FFF #define DAC_DHR12RD_DACC2DHR 0x0FFF0000 +/* Dual DAC 12-bit left-aligned data holding register */ #define DAC_DHR12LD_DACC1DHR 0x0000FFF0 #define DAC_DHR12LD_DACC2DHR 0xFFF00000 +/* Dual DAC 8-bit left-aligned data holding register */ #define DAC_DHR8RD_DACC1DHR 0x000000FF #define DAC_DHR8RD_DACC2DHR 0x0000FF00 -#define DAC_DOR1 0x00000FFF +/* Channel 1 data output register */ +#define DAC_DOR1_DACC1DOR 0x00000FFF + +/* Channel 1 data output register */ +#define DAC_DOR2_DACC2DOR 0x00000FFF -#define DAC_DOR2 0x00000FFF +#define DAC_CH1 0x1 +#define DAC_CH2 0x2 +void dac_init(uint32 flags); -void dac_init(void); -void dac_write(uint8 chan, uint16 val); +void dac_write_channel(uint8 channel, uint16 val); +void dac_enable_channel(uint8 channel); +void dac_disable_channel(uint8 channel); #ifdef __cplusplus } // extern "C" #endif - #endif diff --git a/libmaple/dma.c b/libmaple/dma.c index 15c96e1..c71e52c 100644 --- a/libmaple/dma.c +++ b/libmaple/dma.c @@ -77,31 +77,31 @@ static inline void dispatch_handler(uint8 channel_idx) { } } -void DMAChannel1_IRQHandler(void) { +void __irq_dma1_channel1(void) { dispatch_handler(0); } -void DMAChannel2_IRQHandler(void) { +void __irq_dma1_channel2(void) { dispatch_handler(1); } -void DMAChannel3_IRQHandler(void) { +void __irq_dma2_channel3(void) { dispatch_handler(2); } -void DMAChannel4_IRQHandler(void) { +void __irq_dma2_channel4(void) { dispatch_handler(3); } -void DMAChannel5_IRQHandler(void) { +void __irq_dma2_channel5(void) { dispatch_handler(4); } -void DMAChannel6_IRQHandler(void) { +void __irq_dma2_channel6(void) { dispatch_handler(5); } -void DMAChannel7_IRQHandler(void) { +void __irq_dma2_channel7(void) { dispatch_handler(6); } diff --git a/libmaple/exc.S b/libmaple/exc.S index 2713ee3..7631e48 100644 --- a/libmaple/exc.S +++ b/libmaple/exc.S @@ -41,22 +41,61 @@ # SP--> r0 .text -.globl HardFaultException +.globl __exc_hardfault +.globl __exc_nmi +.globl __exc_hardfault +.globl __exc_memmanage +.globl __exc_busfault +.globl __exc_usagefault + +.code 16 +.thumb_func +__exc_nmi: + mov r0, #1 + b __default_exc + +.thumb_func +__exc_hardfault: + mov r0, #2 + b __default_exc + +.thumb_func +__exc_memmanage: + mov r0, #3 + b __default_exc + +.thumb_func +__exc_busfault: + mov r0, #4 + b __default_exc + +.thumb_func +__exc_usagefault: + mov r0, #5 + b __default_exc + .thumb_func -HardFaultException: - b HardFaultException - ldr r0, CPSR_MASK @ Set default CPSR - push {r0} - ldr r0, TARGET_PC @ Set target pc - push {r0} - sub sp, sp, #24 @ its not like i even care - ldr r0, EXC_RETURN @ Return to thread mode - mov lr, r0 - bx lr @ Exception exit - - .align 4 - CPSR_MASK: .word 0x61000000 - EXC_RETURN: .word 0xFFFFFFF9 - TARGET_PC: .word throb +__default_exc: + ldr r2, NVIC_CCR @ Enable returning to thread mode even if there are + mov r1 ,#1 @ pending exceptions. See flag NONEBASETHRDENA. + str r1, [r2] + cpsid i @ Disable global interrupts + ldr r2, SYSTICK_CSR @ Disable systick handler + mov r1, #0 + str r1, [r2] + ldr r1, CPSR_MASK @ Set default CPSR + push {r1} + ldr r1, TARGET_PC @ Set target pc + push {r1} + sub sp, sp, #24 @ Don't care + ldr r1, EXC_RETURN @ Return to thread mode + mov lr, r1 + bx lr @ Exception exit +.align 4 +CPSR_MASK: .word 0x61000000 +EXC_RETURN: .word 0xFFFFFFF9 +TARGET_PC: .word __error +NVIC_CCR: .word 0xE000ED14 @ NVIC configuration control register +SYSTICK_CSR: .word 0xE000E010 @ Systick control register diff --git a/libmaple/exti.c b/libmaple/exti.c index 150dd05..e8ad52a 100644 --- a/libmaple/exti.c +++ b/libmaple/exti.c @@ -74,32 +74,32 @@ static inline void dispatch_handler(uint32 channel) { * is associated with each channel, so we * don't have to keep track of which channel * we came from */ -void EXTI0_IRQHandler(void) { +void __irq_exti0(void) { dispatch_handler(EXTI0); clear_pending(EXTI0); } -void EXTI1_IRQHandler(void) { +void __irq_exti1(void) { dispatch_handler(EXTI1); clear_pending(EXTI1); } -void EXTI2_IRQHandler(void) { +void __irq_exti2(void) { dispatch_handler(EXTI2); clear_pending(EXTI2); } -void EXTI3_IRQHandler(void) { +void __irq_exti3(void) { dispatch_handler(EXTI3); clear_pending(EXTI3); } -void EXTI4_IRQHandler(void) { +void __irq_exti4(void) { dispatch_handler(EXTI4); clear_pending(EXTI4); } -void EXTI9_5_IRQHandler(void) { +void __irq_exti9_5(void) { /* Figure out which channel it came from */ uint32 pending; uint32 i; @@ -116,7 +116,7 @@ void EXTI9_5_IRQHandler(void) { } } -void EXTI15_10_IRQHandler(void) { +void __irq_exti15_10(void) { /* Figure out which channel it came from */ uint32 pending; uint32 i; diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h index 3e7fea9..6b75c96 100644 --- a/libmaple/libmaple.h +++ b/libmaple/libmaple.h @@ -24,164 +24,50 @@ /** * @file libmaple.h - * - * @brief general include file for libmaple + * @brief General include file for libmaple */ #ifndef _LIBMAPLE_H_ #define _LIBMAPLE_H_ #include "libmaple_types.h" -#include "stm32.h" - -/* General configuration */ -#define DEBUG_NONE 0 -#define DEBUG_FAULT 1 -#define DEBUG_ALL 2 +#include "util.h" -#ifndef DEBUG_LEVEL -#define DEBUG_LEVEL DEBUG_ALL -#endif +/* + * Where to put usercode, based on space reserved for bootloader. + * + * FIXME this has no business being here + */ +#define USER_ADDR_ROM 0x08005000 +#define USER_ADDR_RAM 0x20000C00 +#define STACK_TOP 0x20000800 /* MCU-specific configuration */ #if defined(MCU_STM32F103RB) /* e.g., LeafLabs Maple */ /* Number of GPIO ports (GPIOA, GPIOB, etc.) */ - #define NR_GPIO_PORTS 4 - - /* Total number of GPIO pins */ - #define NR_GPIO_PINS 39 - - /* Number of 16-bit backup registers */ - #define NR_BKP_REGS 10 - - /* Number of timer devices ports, definitely used */ - #define NR_TIMERS 4 - - /* Number of USART ports */ - #define NR_USART 3 - - /* Has an FSMC bus? */ - #define NR_FSMC 0 - - /* Has a DAC? */ - #define NR_DAC_PINS 0 - - /* Number of maskable interrupts */ - #define NR_INTERRUPTS 43 - - /* USB Identifier numbers */ - /* Descriptor strings must be modified by hand in - usb/descriptors.c for now */ - #define VCOM_ID_VENDOR 0x1EAF - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_BANK GPIOC_BASE - #define USB_DISC_PIN 12 - #define USB_CONFIG_MAX_POWER (100 >> 1) - #define RESET_DELAY (100) - - /* Where to put usercode (based on space reserved for bootloader) */ - #define USER_ADDR_ROM 0x08005000 - #define USER_ADDR_RAM 0x20000C00 - #define STACK_TOP 0x20000800 - - /* Debug port settings (from ASSERT) */ - #define ERROR_LED_PORT GPIOB_BASE - #define ERROR_LED_PIN 12 - #define ERROR_USART_NUM USART2 - #define ERROR_USART_BAUD 9600 - #define ERROR_TX_PORT GPIOA_BASE - #define ERROR_TX_PIN 2 - - /* Just in case, most boards have at least some memory */ - #ifndef RAMSIZE - # define RAMSIZE (caddr_t)0x50000 - #endif - - /* Bitbanded Memory sections */ - #define BITBAND_SRAM_REF 0x20000000 - #define BITBAND_SRAM_BASE 0x22000000 - #define BITBAND_PERI_REF 0x40000000 - #define BITBAND_PERI_BASE 0x42000000 + #define NR_GPIO_PORTS 4 + + /* SRAM size, in bytes */ + #define SRAM_SIZE 0x5000 #elif defined(MCU_STM32F103ZE) /* e.g., LeafLabs Maple Native */ - #define NR_GPIO_PORTS 7 - #define NR_GPIO_PINS 100 - #define NR_BKP_REGS 42 /* TODO test on Native */ - #define NR_TIMERS 8 - #define NR_USART 5 /* NB: 4 and 5 are UART only */ - #define NR_FSMC 1 - #define NR_DAC_PINS 2 - #define NR_INTERRUPTS 60 - - #define VCOM_ID_VENDOR 0x1EAF - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_BANK GPIOB_BASE - #define USB_DISC_PIN 8 - #define USB_CONFIG_MAX_POWER (100 >> 1) - #define RESET_DELAY (100) - - #define USER_ADDR_ROM 0x08005000 - #define USER_ADDR_RAM 0x20000C00 - #define STACK_TOP 0x20000800 - - #define ERROR_LED_PORT GPIOC_BASE - #define ERROR_LED_PIN 15 - #define ERROR_USART_NUM USART1 - #define ERROR_USART_BAUD 9600 - #define ERROR_TX_PORT GPIOA_BASE - #define ERROR_TX_PIN 10 - - #ifndef RAMSIZE - # define RAMSIZE (caddr_t)0x50000 - #endif - - #define BITBAND_SRAM_REF 0x20000000 - #define BITBAND_SRAM_BASE 0x22000000 - #define BITBAND_PERI_REF 0x40000000 - #define BITBAND_PERI_BASE 0x42000000 + #define NR_GPIO_PORTS 7 + + #define SRAM_SIZE 0x10000 #elif defined(MCU_STM32F103CB) /* e.g., LeafLabs Maple Mini */ - #define NR_GPIO_PORTS 3 - #define NR_GPIO_PINS 34 - #define NR_BKP_REGS 10 /* TODO test on Mini */ - #define NR_TIMERS 4 - #define NR_USART 3 - #define NR_FSMC 0 - #define NR_DAC_PINS 0 - - #define VCOM_ID_VENDOR 0x1EAF - #define VCOM_ID_PRODUCT 0x0005 - #define USB_DISC_BANK GPIOB_BASE - #define USB_DISC_PIN 9 - #define USB_CONFIG_MAX_POWER (100 >> 1) - #define RESET_DELAY 100 - - #define USER_ADDR_ROM 0x08005000 - #define USER_ADDR_RAM 0x20000C00 - #define STACK_TOP 0x20000800 - - #define ERROR_LED_PORT GPIOB_BASE - #define ERROR_LED_PIN 12 - #define ERROR_USART_NUM USART2 - #define ERROR_USART_BAUD 9600 - #define ERROR_TX_PORT GPIOA_BASE - #define ERROR_TX_PIN 2 - - #ifndef RAMSIZE - # define RAMSIZE (caddr_t)0x50000 - #endif - - /* Bitbanded Memory sections */ - #define BITBAND_SRAM_REF 0x20000000 - #define BITBAND_SRAM_BASE 0x22000000 - #define BITBAND_PERI_REF 0x40000000 - #define BITBAND_PERI_BASE 0x42000000 + /* Note that this is not, strictly speaking, true. But only pins + 0 and 1 exist, and they're used for OSC on the Mini, so we'll + live with this for now. */ + #define NR_GPIO_PORTS 3 + + #define SRAM_SIZE 0x5000 #else @@ -190,8 +76,5 @@ #endif -/* Requires board configuration info */ -#include "util.h" - #endif diff --git a/libmaple/libmaple_types.h b/libmaple/libmaple_types.h index 8d216a8..a976a9e 100644 --- a/libmaple/libmaple_types.h +++ b/libmaple/libmaple_types.h @@ -45,8 +45,6 @@ typedef void (*voidFuncPtr)(void); #define __io volatile -#define ALWAYS_INLINE inline __attribute__((always_inline)) - #ifndef NULL #define NULL 0 #endif diff --git a/libmaple/pwr.c b/libmaple/pwr.c new file mode 100644 index 0000000..b43193e --- /dev/null +++ b/libmaple/pwr.c @@ -0,0 +1,42 @@ +/****************************************************************************** + * 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. + *****************************************************************************/ + +#include "pwr.h" +#include "rcc.h" + +pwr_dev pwr = { + .regs = PWR_BASE; +}; + +const pwr_dev *PWR = &pwr; + +/** + * Enables the power interface clock, and resets the power device. + */ +void pwr_init(void) { + rcc_clk_enable(RCC_PWR); + rcc_reset_dev(RCC_PWR); +} diff --git a/libmaple/pwr.h b/libmaple/pwr.h index 96a8356..5ff815d 100644 --- a/libmaple/pwr.h +++ b/libmaple/pwr.h @@ -29,18 +29,52 @@ * @brief Power control (PWR) defines. */ -#define PWR_BASE 0x40007000 - -#define PWR_CR (PWR_BASE + 0x0) -#define PWR_CR_DBP 8 /* Disable backup domain write protection bit */ -#define PWR_CR_PVDE 4 /* Power voltage detector enable bit */ -#define PWR_CR_CSBF 3 /* Clear standby flag bit */ -#define PWR_CR_CWUF 2 /* Clear wakeup flag bit */ -#define PWR_CR_PDDS 1 /* Power down deepsleep bit */ -#define PWR_CR_LPDS 0 /* Low-power deepsleep bit */ - -#define PWR_CSR (PWR_BASE + 0x4) -#define PWR_CSR_EWUP 8 /* Enable wakeup pin bit */ -#define PWR_CSR_PVDO 2 /* PVD output bit */ -#define PWR_CSR_SBF 1 /* Standby flag bit */ -#define PWR_CSR_WUF 0 /* Wakeup flag bit */ +#include "libmaple.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Power interface register map. */ +typedef struct pwr_reg_map { + __io uint32 CR; /**< Control register */ + __io uint32 CSR; /**< Control and status register */ +} pwr_reg_map; + +/* + * Power peripheral base. + */ +#define PWR_BASE ((pwr_reg_map*)0x40007000) + +/** Power interface device. */ +typedef struct pwr_dev { + pwr_reg_map *regs; +} pwr_dev; + +/** + * Power device. + */ +extern const pwr_dev *PWR; +/* + * Register bit definitions + */ + +/* Control register */ +#define PWR_CR_DBP 8 /**< Disable backup domain write protection bit */ +#define PWR_CR_PVDE 4 /**< Power voltage detector enable bit */ +#define PWR_CR_CSBF 3 /**< Clear standby flag bit */ +#define PWR_CR_CWUF 2 /**< Clear wakeup flag bit */ +#define PWR_CR_PDDS 1 /**< Power down deepsleep bit */ +#define PWR_CR_LPDS 0 /**< Low-power deepsleep bit */ + +/* Control and status register */ +#define PWR_CSR_EWUP 8 /**< Enable wakeup pin bit */ +#define PWR_CSR_PVDO 2 /**< PVD output bit */ +#define PWR_CSR_SBF 1 /**< Standby flag bit */ +#define PWR_CSR_WUF 0 /**< Wakeup flag bit */ + +void pwr_init(void); + +#ifdef __cplusplus +} +#endif diff --git a/libmaple/rcc.c b/libmaple/rcc.c index 8edccd9..d3fb6a3 100644 --- a/libmaple/rcc.c +++ b/libmaple/rcc.c @@ -54,6 +54,7 @@ static const struct rcc_dev_info rcc_dev_table[] = { [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 }, [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 }, + [RCC_ADC3] = { .clk_domain = APB2, .line_num = 15 }, [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 }, [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, @@ -73,6 +74,8 @@ static const struct rcc_dev_info rcc_dev_table[] = { [RCC_DAC] = { .clk_domain = APB1, .line_num = 29 }, // High-density only [RCC_DMA1] = { .clk_domain = AHB, .line_num = 0 }, [RCC_DMA2] = { .clk_domain = AHB, .line_num = 1 }, // High-density only + [RCC_PWR] = { .clk_domain = APB1, .line_num = 28}, + [RCC_BKP] = { .clk_domain = APB1, .line_num = 27} [RCC_I2C1] = { .clk_domain = APB1, .line_num = 21 }, // High-density only [RCC_I2C2] = { .clk_domain = APB1, .line_num = 22 }, // High-density only }; @@ -118,18 +121,18 @@ void rcc_clk_init(uint32 sysclk_src, uint32 pll_src, uint32 pll_mul) { /** * @brief Turn on the clock line on a device - * @param dev_num device to turn on + * @param device Clock ID of the device to turn on. */ -void rcc_clk_enable(uint32 dev_num) { +void rcc_clk_enable(rcc_clk_id device) { static const uint32 enable_regs[] = { [APB1] = RCC_APB1ENR, [APB2] = RCC_APB2ENR, [AHB] = RCC_AHBENR, }; - uint8 clk_domain = rcc_dev_table[dev_num].clk_domain; + uint8 clk_domain = rcc_dev_table[device].clk_domain; - __set_bits(enable_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); + __set_bits(enable_regs[clk_domain], BIT(rcc_dev_table[device].line_num)); } /** @@ -155,16 +158,16 @@ void rcc_set_prescaler(uint32 prescaler, uint32 divider) { /** * @brief reset a device - * @param dev_num device to reset + * @param device Clock ID of the device to reset. */ -void rcc_reset_dev(uint32 dev_num) { +void rcc_reset_dev(rcc_clk_id device) { static const uint32 reset_regs[] = { [APB1] = RCC_APB1RSTR, [APB2] = RCC_APB2RSTR, }; - uint8 clk_domain = rcc_dev_table[dev_num].clk_domain; + uint8 clk_domain = rcc_dev_table[device].clk_domain; - __set_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); - __clear_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); + __set_bits(reset_regs[clk_domain], BIT(rcc_dev_table[device].line_num)); + __clear_bits(reset_regs[clk_domain], BIT(rcc_dev_table[device].line_num)); } diff --git a/libmaple/rcc.h b/libmaple/rcc.h index 1a59219..569da57 100644 --- a/libmaple/rcc.h +++ b/libmaple/rcc.h @@ -144,8 +144,10 @@ enum { RCC_PRESCALER_ADC }; -// RCC Devices -enum { +/* + * Identifies bus and clock line for a device + */ +typedef enum { RCC_GPIOA, RCC_GPIOB, RCC_GPIOC, @@ -156,6 +158,7 @@ enum { RCC_AFIO, RCC_ADC1, RCC_ADC2, + RCC_ADC3, RCC_USART1, RCC_USART2, RCC_USART3, @@ -175,14 +178,16 @@ enum { RCC_DAC, // High-density devices only (Maple Native) RCC_DMA1, RCC_DMA2, // High-density devices only (Maple Native) + RCC_PWR, + RCC_BKP, RCC_I2C1, RCC_I2C2 -}; +} rcc_clk_id; void rcc_clk_init(uint32 sysclk_src, uint32 pll_src, uint32 pll_mul); -void rcc_clk_enable(uint32 dev); -void rcc_reset_dev(uint32 dev); +void rcc_clk_enable(rcc_clk_id device); +void rcc_reset_dev(rcc_clk_id device); void rcc_set_prescaler(uint32 prescaler, uint32 divider); #ifdef __cplusplus diff --git a/libmaple/systick.c b/libmaple/systick.c index b056001..b9a52c1 100644 --- a/libmaple/systick.c +++ b/libmaple/systick.c @@ -64,6 +64,6 @@ void systick_resume() { } /** SysTick interrupt handler. Bumps up the tick counter. */ -void SysTickHandler(void) { +void __exc_systick(void) { systick_timer_millis++; } diff --git a/libmaple/timers.c b/libmaple/timers.c index 29aeeba..c561d39 100644 --- a/libmaple/timers.c +++ b/libmaple/timers.c @@ -55,7 +55,7 @@ struct timer_dev timer_dev_table[] = { .rcc_dev_num = RCC_TIMER4, .nvic_dev_num = NVIC_TIMER4 }, -#if NR_TIMERS >= 8 +#ifdef STM32_HIGH_DENSITY /* High density devices only (eg, Maple Native) */ [TIMER5] = { .base = (timer_port*)TIMER5_BASE, @@ -82,7 +82,7 @@ void timer_init(timer_dev_num timer_num, uint16 prescale) { if (timer_num == TIMER1) { is_advanced = 1; } -#if NR_TIMERS >= 8 +#ifdef STM32_HIGH_DENSITY if (timer_num == TIMER8) { is_advanced = 1; } @@ -193,12 +193,8 @@ void timer_set_reload(timer_dev_num timer_num, uint16 max_reload) { * or similar to prevent interrupts and PWM output without 16 seperate function * calls to timer_set_mode */ void timer_disable_all(void) { - // TODO: refactor - - /* Note: this must be very robust because it gets called from, - e.g., ASSERT */ timer_port *timer; -#if NR_TIMERS >= 8 +#ifdef STM32_HIGH_DENSITY timer_port *timers[6] = { (timer_port*)TIMER1_BASE, (timer_port*)TIMER2_BASE, (timer_port*)TIMER3_BASE, @@ -386,7 +382,7 @@ void timer_generate_update(timer_dev_num timer_num) { * registers /or/ has overflowed. * * This is a rather long implementation... */ -void TIM1_CC_IRQHandler(void) { +void __irq_tim1_cc(void) { timer_port *timer = (timer_port*)TIMER1_BASE; uint16 sr_buffer; sr_buffer = timer->SR; @@ -422,7 +418,7 @@ void TIM1_CC_IRQHandler(void) { //timer->EGR = 1; } } -void TIM2_IRQHandler(void) { +void __irq_tim2(void) { /* This is a rather long implementation... */ timer_port *timer = (timer_port*)TIMER2_BASE; uint16 sr_buffer; @@ -457,7 +453,7 @@ void TIM2_IRQHandler(void) { //timer->EGR = 1; } } -void TIM3_IRQHandler(void) { +void __irq_tim3(void) { /* This is a rather long implementation... */ timer_port *timer = (timer_port*)TIMER3_BASE; uint16 sr_buffer; @@ -493,7 +489,7 @@ void TIM3_IRQHandler(void) { } } -void TIM4_IRQHandler(void) { +void __irq_tim4(void) { /* This is a rather long implementation... */ timer_port*timer = (timer_port*)TIMER4_BASE; uint16 sr_buffer; diff --git a/libmaple/timers.h b/libmaple/timers.h index 99bcab6..1f6afcd 100644 --- a/libmaple/timers.h +++ b/libmaple/timers.h @@ -206,7 +206,7 @@ typedef enum { TIMER2, /*< General purpose timer TIM2 */ TIMER3, /*< General purpose timer TIM3 */ TIMER4, /*< General purpose timer TIM4 */ -#if NR_TIMERS >= 8 +#ifdef STM32_HIGH_DENSITY TIMER5, /*< General purpose timer TIM5; high density only */ /* FIXME maple native: put timers 6 and 7 back in and make the corresponding changes to timers.c */ @@ -412,8 +412,8 @@ void timer_generate_update(timer_dev_num timer_num); /** * Turn on PWM with duty_cycle. * - * @param ccr TIMERx_CHn_CCR, where x goes from 1 to NR_TIMERS, - * and n goes from 1 to 4. + * @param ccr TIMERx_CHn_CCR, where x ranges over timers, and n ranges + * from 1 to 4. * * @param duty_cycle: A number between 0 and * timer_get_compare_value(TIMERx, y), where x and y are as above. diff --git a/libmaple/usart.c b/libmaple/usart.c index 44a5c92..494a29f 100644 --- a/libmaple/usart.c +++ b/libmaple/usart.c @@ -61,7 +61,7 @@ struct usart_dev usart_dev_table[] = { .rcc_dev_num = RCC_USART3, .nvic_dev_num = NVIC_USART3 }, -#if NR_USART >= 5 +#ifdef STM32_HIGH_DENSITY /* TODO test */ [UART4] = { .base = (usart_port*)UART4_BASE, @@ -95,24 +95,24 @@ static inline void usart_irq(int usart_num) { /* TODO: Check the disassembly for the following functions to make sure GCC inlined properly. */ -void USART1_IRQHandler(void) { +void __irq_usart1(void) { usart_irq(USART1); } -void USART2_IRQHandler(void) { +void __irq_usart2(void) { usart_irq(USART2); } -void USART3_IRQHandler(void) { +void __irq_usart3(void) { usart_irq(USART3); } -#if NR_USART >= 5 -void UART4_IRQHandler(void) { +#ifdef STM32_HIGH_DENSITY +void __irq_uart4(void) { usart_irq(UART4); } -void UART5_IRQHandler(void) { +void __irq_uart5(void) { usart_irq(UART5); } #endif @@ -124,7 +124,11 @@ void UART5_IRQHandler(void) { * @param baud Baud rate to be set at */ void usart_init(uint8 usart_num, uint32 baud) { - ASSERT(usart_num <= NR_USART); +#ifdef STM32_HIGH_DENSITY + ASSERT(usart_num <= UART5); +#else + ASSERT(usart_num <= USART3); +#endif usart_port *port; ring_buffer *ring_buf; @@ -170,7 +174,7 @@ void usart_disable_all() { usart_disable(USART1); usart_disable(USART2); usart_disable(USART3); -#if NR_USART >= 5 +#ifdef STM32_HIGH_DENSITY usart_disable(UART4); usart_disable(UART5); #endif diff --git a/libmaple/usart.h b/libmaple/usart.h index 0ca3f55..90b3415 100644 --- a/libmaple/usart.h +++ b/libmaple/usart.h @@ -43,8 +43,10 @@ enum { USART1, USART2, USART3, +#ifdef STM32_HIGH_DENSITY UART4, UART5, +#endif }; /* peripheral register struct */ diff --git a/libmaple/usb/descriptors.c b/libmaple/usb/descriptors.c index 360e6dd..8dd9521 100644 --- a/libmaple/usb/descriptors.c +++ b/libmaple/usb/descriptors.c @@ -150,43 +150,50 @@ const USB_Descriptor_Config usbVcomDescriptor_Config = { // } }; -/* - String Identifiers: +/***************************************************************************** + ***************************************************************************** + *** + *** FIXME FIXME FIXME NOT THE RIGHT THING! MOVE ALL THIS INTO TO WIRISH! + *** + ***************************************************************************** + *****************************************************************************/ - we may choose to specify any or none of the following string - identifiers: +const uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)] = { + USB_DESCRIPTOR_STRING_LEN(1), + USB_DESCRIPTOR_TYPE_STRING, + 0x09, + 0x04 +}; - iManufacturer: LeafLabs - iProduct: Maple R3 - iSerialNumber: NONE - iConfiguration: NONE - iInterface(CCI): NONE - iInterface(DCI): NONE +const uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)] = { + USB_DESCRIPTOR_STRING_LEN(8), + USB_DESCRIPTOR_TYPE_STRING, + 'L', 0, 'e', 0, 'a', 0, 'f', 0, + 'L', 0, 'a', 0, 'b', 0, 's', 0 +}; - additionally we must provide the unicode language identifier, - which is 0x0409 for US English -*/ +/* + String Identifiers: -const uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)] = -{ - USB_DESCRIPTOR_STRING_LEN(1), - USB_DESCRIPTOR_TYPE_STRING, - 0x09, - 0x04 -}; + we may choose to specify any or none of the following string + identifiers: -const uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)] = -{ - USB_DESCRIPTOR_STRING_LEN(8), - USB_DESCRIPTOR_TYPE_STRING, - 'L', 0, 'e', 0, 'a', 0, 'f', 0, - 'L', 0, 'a', 0, 'b', 0, 's', 0 -}; + iManufacturer: LeafLabs + iProduct: Maple R3 + iSerialNumber: NONE + iConfiguration: NONE + iInterface(CCI): NONE + iInterface(DCI): NONE -const uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)] = -{ - USB_DESCRIPTOR_STRING_LEN(8), - USB_DESCRIPTOR_TYPE_STRING, - 'M', 0, 'a', 0, 'p', 0, 'l', 0, - 'e', 0, ' ', 0, 'R', 0, '3', 0 + additionally we must provide the unicode language identifier, + which is 0x0409 for US English +*/ +const uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)] = { + USB_DESCRIPTOR_STRING_LEN(8), + USB_DESCRIPTOR_TYPE_STRING, + 'M', 0, 'a', 0, 'p', 0, 'l', 0, + 'e', 0, ' ', 0, ' ', 0, ' ', 0 }; + +/***************************************************************************** + *****************************************************************************/ diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c index d875785..62f56fc 100644 --- a/libmaple/usb/usb.c +++ b/libmaple/usb/usb.c @@ -241,7 +241,7 @@ void usbDsbISR(void) { } /* overloaded ISR routine, this is the main usb ISR */ -void usb_lpIRQHandler(void) { +void __irq_usb_lp_can_rx0(void) { wIstr = _GetISTR(); /* go nuts with the preproc switches since this is an ISTR and must be FAST */ diff --git a/libmaple/usb/usb.h b/libmaple/usb/usb.h index 0ed02e5..92f606c 100644 --- a/libmaple/usb/usb.h +++ b/libmaple/usb/usb.h @@ -69,7 +69,7 @@ void usbDsbISR(void); void usbEnbISR(void); /* overloaded ISR routine, this is the main usb ISR */ -void usb_lpIRQHandler(void); +void __irq_usb_lp_can_rx0(void); void usbWaitReset(void); /* blocking functions for send/receive */ diff --git a/libmaple/usb/usb_config.h b/libmaple/usb/usb_config.h index e5f3979..394c580 100644 --- a/libmaple/usb/usb_config.h +++ b/libmaple/usb/usb_config.h @@ -5,6 +5,67 @@ #include "usb_lib.h" +/****************************************************************************** + ****************************************************************************** + *** + *** HACK ALERT + *** + *** FIXME FIXME FIXME FIXME + *** + *** A bunch of board-specific #defines that are only used by the + *** USB routines got put into libmaple.h for what appear to be + *** historical reasons. I'm [mbolivar] putting them in here for + *** now, so that we can treat the usb/ directory as a black box, + *** freeing the rest of libmaple/ to be implemented as a + *** general-purpose STM32 library. All of this REALLY needs to get + *** moved into wirish when we get a chance to redo the USB stack. + *** + ****************************************************************************** + *****************************************************************************/ + +#define VCOM_ID_VENDOR 0x1EAF +#define RESET_DELAY (100) +#define USB_CONFIG_MAX_POWER (100 >> 1) + +#if defined(BOARD_maple) + + /* USB Identifier numbers */ + #define VCOM_ID_PRODUCT 0x0004 + #define USB_DISC_BANK GPIOC_BASE + #define USB_DISC_PIN 12 + +#elif defined(BOARD_maple_mini) + + #define VCOM_ID_PRODUCT 0x0005 + #define USB_DISC_BANK GPIOB_BASE + #define USB_DISC_PIN 9 + +#elif defined(BOARD_maple_native) + + #define VCOM_ID_PRODUCT 0x0006 + #define USB_DISC_BANK GPIOB_BASE + #define USB_DISC_PIN 8 + +#else + +#error ("Sorry! the USB stack relies on LeafLabs board-specific " \ + "configuration right now. If you want, you can pretend you're one " \ + "of our boards; i.e., #define BOARD_maple, BOARD_maple_mini, or " \ + "BOARD_maple_native according to what matches your MCU best. " \ + "You should also take a look at libmaple/usb/descriptors.c; we make " \ + "some assumptions there that you probably won't like.") + +#endif + +/****************************************************************************** + ****************************************************************************** + *** + *** END HACK + *** + ****************************************************************************** + *****************************************************************************/ + + /* choose addresses to give endpoints the max 64 byte buffers */ #define USB_BTABLE_ADDRESS 0x00 #define VCOM_CTRL_EPNUM 0x00 @@ -33,14 +94,15 @@ #define NUM_ENDPTS 0x04 /* handle all usb interrupts */ -#define ISR_MSK ( CNTR_CTRM | \ - CNTR_WKUPM | \ - CNTR_SUSPM | \ - CNTR_ERRM | \ - CNTR_SOFM | \ - CNTR_ESOFM | \ - CNTR_RESETM ) +#define ISR_MSK (CNTR_CTRM | \ + CNTR_WKUPM | \ + CNTR_SUSPM | \ + CNTR_ERRM | \ + CNTR_SOFM | \ + CNTR_ESOFM | \ + CNTR_RESETM) #define F_SUSPEND_ENABLED 1 + #endif diff --git a/libmaple/util.c b/libmaple/util.c index 135f005..3408a2e 100644 --- a/libmaple/util.c +++ b/libmaple/util.c @@ -34,25 +34,58 @@ #include "adc.h" #include "timers.h" -/* Error assert + fade */ -void _fail(const char* file, int line, const char* exp) { - int32 slope = 1; - uint32 CC = 0x0000; - uint32 TOP_CNT = 0x02FF; - uint32 i = 0; +/* Failed asserts send out a message on this USART. */ +#ifndef ERROR_USART_NUM +#define ERROR_USART_NUM USART2 +#define ERROR_USART_BAUD 9600 +#define ERROR_TX_PORT GPIOA_BASE +#define ERROR_TX_PIN 2 +#endif + +/* If you define ERROR_LED_PORT and ERROR_LED_PIN, then a failed + assert will also throb an LED connected to that port an pin. + FIXME this should work together with wirish somehow. */ +#if defined(ERROR_LED_PORT) && defined(ERROR_LED_PIN) +#define HAVE_ERROR_LED +#endif - /* Turn off interrupts */ +/** + * @brief Disables all peripheral interrupts except USB and fades the + * error LED. + * + * Called from exc.S with global interrupts disabled. + */ +void __error(void) { + /* Turn off peripheral interrupts */ nvic_irq_disable_all(); /* Turn off timers */ timer_disable_all(); /* Turn off ADC */ - adc_disable(); + adc_disable_all(); /* Turn off all usarts */ usart_disable_all(); + /* Turn the USB interrupt back on so the bootloader keeps on functioning */ + nvic_irq_enable(NVIC_INT_USBHP); + nvic_irq_enable(NVIC_INT_USBLP); + + /* Reenable global interrupts */ + nvic_globalirq_enable(); + throb(); +} + +/** + * @brief Prints an error message on a uart upon a failed assertion + * and error throbs. + * @param file Source file of failed assertion + * @param line Source line of failed assertion + * @param exp String representation of failed assertion + * @sideeffect Turns of all peripheral interrupts except USB. + */ +void _fail(const char* file, int line, const char* exp) { /* Initialize the error usart */ gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_MODE_AF_OUTPUT_PP); usart_init(ERROR_USART_NUM, ERROR_USART_BAUD); @@ -67,18 +100,17 @@ void _fail(const char* file, int line, const char* exp) { usart_putc(ERROR_USART_NUM, '\n'); usart_putc(ERROR_USART_NUM, '\r'); - /* Turn on the error LED */ - gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); - - /* Turn the USB interrupt back on so the bootloader keeps on functioning */ - nvic_irq_enable(NVIC_INT_USBHP); - nvic_irq_enable(NVIC_INT_USBLP); - /* Error fade */ - throb(); + __error(); } + +/** + * @brief Fades the error LED on and off + * @sideeffect Sets output push-pull on ERROR_LED_PIN. + */ void throb(void) { +#ifdef HAVE_ERROR_LED int32 slope = 1; uint32 CC = 0x0000; uint32 TOP_CNT = 0x0200; @@ -105,5 +137,10 @@ void throb(void) { } i++; } +#else + /* No error LED is connected; do nothing. */ + while (1) + ; +#endif } diff --git a/libmaple/util.h b/libmaple/util.h index 64782d9..fb524c2 100644 --- a/libmaple/util.h +++ b/libmaple/util.h @@ -32,7 +32,18 @@ #ifndef _UTIL_H_ #define _UTIL_H_ -#include "libmaple.h" +#ifdef __cplusplus +extern "C"{ +#endif + +/* Debug configuration */ +#define DEBUG_NONE 0 +#define DEBUG_FAULT 1 +#define DEBUG_ALL 2 + +#ifndef DEBUG_LEVEL +#define DEBUG_LEVEL DEBUG_ALL +#endif #define BIT(shift) (1UL << (shift)) #define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift)) @@ -41,10 +52,16 @@ #define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m))) /* Bit-banding macros */ +/* Bitbanded Memory sections */ +#define BITBAND_SRAM_REF 0x20000000 +#define BITBAND_SRAM_BASE 0x22000000 +#define BITBAND_PERI_REF 0x40000000 +#define BITBAND_PERI_BASE 0x42000000 /* Convert SRAM address */ #define BITBAND_SRAM(a,b) ((BITBAND_SRAM_BASE+(a-BITBAND_SRAM_REF)*32+(b*4))) -/* Convert PERI address */ -#define BITBAND_PERI(a,b) ((BITBAND_PERI_BASE+(a-BITBAND_PERI_REF)*32+(b*4))) +/* Convert peripheral address */ +#define BITBAND_PERI(a, b) ((BITBAND_PERI_BASE + \ + ((uint32)a - BITBAND_PERI_REF) * 32 + (b * 4))) #define REG_SET(reg, val) (*(volatile uint32*)(reg) = (val)) #define REG_SET_BIT(reg, bit) (*(volatile uint32*)(reg) |= BIT(bit)) @@ -62,18 +79,10 @@ #define __write(reg, value) (*(volatile uint32*)(reg) = (value)) #define IS_POWER_OF_TWO(v) (v && !(v & (v - 1))) - -#ifdef __cplusplus -extern "C"{ -#endif - +void __error(void); void _fail(const char*, int, const char*); void throb(void); -#ifdef __cplusplus -} // extern "C" -#endif - /* Asserts for sanity checks, redefine DEBUG_LEVEL in libmaple.h to * compile out these checks */ @@ -99,5 +108,9 @@ void throb(void); #define ASSERT_FAULT(exp) (void)((0)) #endif +#ifdef __cplusplus +} // extern "C" +#endif + #endif diff --git a/support/ld/common_ram.inc b/support/ld/common_ram.inc new file mode 100644 index 0000000..be83e84 --- /dev/null +++ b/support/ld/common_ram.inc @@ -0,0 +1,221 @@ +/* Linker script for STM32 (by Lanchon with Mods by LeafLabs) */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +SEARCH_DIR(.) +/* + * Link against libgcc, libc, and libm + */ +GROUP(libgcc.a libc.a libm.a) + +/* These force the linker to search for particular symbols from + * the start of the link process and thus ensure the user's + * overrides are picked up + */ +INCLUDE names.inc + +/* STM32 vector table. See stm32_vector_table.S */ +EXTERN(__cs3_stm32_vector_table) + +/* libcs3 C start function. See cs3.h */ +EXTERN(__cs3_start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. */ +EXTERN(__cs3_stack) +PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram); + +/* Reset vector and chip reset entry point. See start.S */ +EXTERN(_start) +ENTRY(_start) +PROVIDE(__cs3_reset = _start); + +/* Beginning of the heap */ +PROVIDE(__cs3_heap_start = _end); + +/* End of the heap */ +PROVIDE(__cs3_heap_end = __cs3_region_start_ram + LENGTH(ram)); + + +SECTIONS +{ + .text : + { + CREATE_OBJECT_SYMBOLS + __cs3_region_start_ram = .; + *(.cs3.region-head.ram) + + /* + * STM32 vector table + */ + __cs3_interrupt_vector = __cs3_stm32_vector_table; + *(.cs3.interrupt_vector) + /* Make sure we pulled in an interrupt vector. */ + ASSERT (. != __cs3_stm32_vector_table, "No interrupt vector"); + + /* + * Program code and vague linking + */ + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.rodata .rodata.* .gnu.linkonce.r.*) + + *(.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)) + + . = ALIGN(4); + __cs3_regions = .; + LONG (0) + LONG (__cs3_region_init_ram) + LONG (__cs3_region_start_ram) + LONG (__cs3_region_init_size_ram) + LONG (__cs3_region_zero_size_ram) + } > ram + + /* + * .ARM.exidx exception unwinding + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ram + __exidx_end = .; + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + _etext = .; + } > ram + + .cs3.rom : + { + __cs3_region_start_rom = .; + *(.cs3.region-head.rom) + *(.rom) + . = ALIGN (8); + } >ram + + .cs3.rom.bss : + { + *(.rom.b) + . = ALIGN (8); + } >ram + /* __cs3_region_end_rom is deprecated */ + __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(ram); + __cs3_region_size_rom = LENGTH(ram); + __cs3_region_init_rom = LOADADDR (.cs3.rom); + __cs3_region_init_size_rom = SIZEOF(.cs3.rom); + __cs3_region_zero_size_rom = SIZEOF(.cs3.rom.bss); + + /* + * Start of data + */ + .data : + { + KEEP(*(.jcr)) + *(.got.plt) *(.got) + *(.shdata) + *(.data .data.* .gnu.linkonce.d.*) + *(.ram) + . = ALIGN (8); + _edata = .; + } > ram + + .bss : + { + *(.shbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + *(.ram.b) + . = ALIGN (8); + _end = .; + __end = .; + } > ram + + /* __cs3_region_end_ram is deprecated */ + __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram); + __cs3_region_size_ram = LENGTH(ram); + __cs3_region_init_ram = LOADADDR (.text); + __cs3_region_init_size_ram = _edata - ADDR (.text); + __cs3_region_zero_size_ram = _end - _edata; + __cs3_region_num = 1; + + /* + * 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) } +} diff --git a/support/ld/common_rom.inc b/support/ld/common_rom.inc new file mode 100644 index 0000000..e0c295f --- /dev/null +++ b/support/ld/common_rom.inc @@ -0,0 +1,223 @@ +/* Linker script for STM32 (by Lanchon with Mods by LeafLabs) */ + +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +ENTRY(_start) +SEARCH_DIR(.) +/* + * Link against libgcc, libc, and libm + */ +GROUP(libgcc.a libc.a libm.a) + +/* These force the linker to search for particular symbols from + * the start of the link process and thus ensure the user's + * overrides are picked up + */ +INCLUDE names.inc + +/* STM32 vector table. See stm32_vector_table.S */ +EXTERN(__cs3_stm32_vector_table) + +/* libcs3 C start function. See cs3.h */ +EXTERN(__cs3_start_c) + +/* main entry point */ +EXTERN(main) + +/* Initial stack pointer value. */ +EXTERN(__cs3_stack) +PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram); + +/* Reset vector and chip reset entry point. See start.S */ +EXTERN(_start) +PROVIDE(__cs3_reset = _start); + +/* Beginning of the heap */ +PROVIDE(__cs3_heap_start = _end); + +/* End of the heap */ +PROVIDE(__cs3_heap_end = __cs3_region_start_ram + LENGTH(ram)); + + +SECTIONS +{ + .text : + { + CREATE_OBJECT_SYMBOLS + __cs3_region_start_rom = .; + *(.cs3.region-head.rom) + + /* + * STM32 vector table + */ + __cs3_interrupt_vector = __cs3_stm32_vector_table; + *(.cs3.interrupt_vector) + /* Make sure we pulled in an interrupt vector. */ + ASSERT (. != __cs3_stm32_vector_table, "No interrupt vector"); + + *(.rom) + *(.rom.b) + + /* + * Program code and vague linking + */ + *(.rom) + *(.rom.b) + *(.text .text.* .gnu.linkonce.t.*) + *(.plt) + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) + + *(.rodata .rodata.* .gnu.linkonce.r.*) + + *(.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)) + + . = ALIGN(4); + __cs3_regions = .; + LONG (0) + LONG (__cs3_region_init_ram) + LONG (__cs3_region_start_ram) + LONG (__cs3_region_init_size_ram) + LONG (__cs3_region_zero_size_ram) + } > REGION_TEXT + + /* + * .ARM.exidx exception unwinding + */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > REGION_TEXT + __exidx_end = .; + + /* + * End of text + */ + .text.align : + { + . = ALIGN(8); + _etext = .; + } > REGION_TEXT + + /* expose a custom rom only section */ + .USER_FLASH : + { + *(.USER_FLASH) + } >rom + + /* __cs3_region_end_rom is deprecated */ + __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom); + __cs3_region_size_rom = LENGTH(rom); + __cs3_region_num = 1; + + /* + * Start of data + */ + .data : + { + ram_begin = DEFINED(RAM_BUILD) ? . : . ; + *(.cs3.region-head.ram_begin) + + __cs3_region_start_ram = .; + *(.cs3.region-head.ram) + + KEEP(*(.jcr)) + *(.got.plt) *(.got) + *(.shdata) + *(.data .data.* .gnu.linkonce.d.*) + *(.ram) + . = ALIGN (8); + _edata = .; + } > REGION_DATA AT> REGION_TEXT + + .bss : + { + *(.shbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + *(.ram.b) + . = ALIGN (8); + _end = .; + __end = .; + } > REGION_BSS AT> REGION_TEXT + + /* __cs3_region_end_ram is deprecated */ + __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram); + __cs3_region_size_ram = LENGTH(ram); + __cs3_region_init_ram = LOADADDR (.data); + __cs3_region_init_size_ram = _edata - ADDR (.data); + __cs3_region_zero_size_ram = _end - _edata; + __cs3_region_num = 1; + + /* + * 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) } +} diff --git a/support/ld/libcs3-lanchon-stm32.a b/support/ld/libcs3-lanchon-stm32.a Binary files differdeleted file mode 100644 index 4ed858f..0000000 --- a/support/ld/libcs3-lanchon-stm32.a +++ /dev/null diff --git a/support/ld/libcs3-lanchon-stm32.tar.gz b/support/ld/libcs3-lanchon-stm32.tar.gz Binary files differdeleted file mode 100644 index 5cbcf7d..0000000 --- a/support/ld/libcs3-lanchon-stm32.tar.gz +++ /dev/null diff --git a/support/ld/libcs3_stm32_high_density.a b/support/ld/libcs3_stm32_high_density.a Binary files differnew file mode 100644 index 0000000..472ed28 --- /dev/null +++ b/support/ld/libcs3_stm32_high_density.a diff --git a/support/ld/libcs3_stm32_med_density.a b/support/ld/libcs3_stm32_med_density.a Binary files differnew file mode 100644 index 0000000..07a991d --- /dev/null +++ b/support/ld/libcs3_stm32_med_density.a diff --git a/support/ld/libcs3_stm32_src/Makefile b/support/ld/libcs3_stm32_src/Makefile new file mode 100644 index 0000000..d5275b9 --- /dev/null +++ b/support/ld/libcs3_stm32_src/Makefile @@ -0,0 +1,35 @@ +# setup environment
+
+TARGET_ARCH = -mcpu=cortex-m3 -mthumb
+
+CC = arm-none-eabi-gcc
+CFLAGS =
+
+AS = $(CC) -x assembler-with-cpp -c $(TARGET_ARCH)
+ASFLAGS =
+
+AR = arm-none-eabi-ar
+ARFLAGS = cr
+
+LIB_OBJS = stm32_vector_table.o stm32_isrs.o start.o start_c.o
+
+help:
+ @echo "Targets:"
+ @echo "\t medium-density: Target medium density chips (e.g. Maple)"
+ @echo "\t high-density: Target high density chips (e.g. Maple-native)"
+
+.PHONY: help medium high
+
+medium-density: $(LIB_OBJS)
+ $(AR) $(ARFLAGS) libcs3_stm32_med_density.a $(LIB_OBJS)
+ rm -f $(LIB_OBJS)
+
+high-density: CFLAGS := -DSTM32_HIGH_DENSITY
+high-density: $(LIB_OBJS)
+ $(AR) $(ARFLAGS) libcs3_stm32_high_density.a $(LIB_OBJS)
+ rm -f $(LIB_OBJS)
+
+# clean
+.PHONY: clean
+clean:
+ -rm -f $(LIB_OBJS) *.a
diff --git a/support/ld/libcs3_stm32_src/start.S b/support/ld/libcs3_stm32_src/start.S new file mode 100644 index 0000000..ae75747 --- /dev/null +++ b/support/ld/libcs3_stm32_src/start.S @@ -0,0 +1,27 @@ +/*
+ * 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,=__cs3_stack
+ mov sp,r1
+ ldr r1,=__cs3_start_c
+ bx r1
+ .pool
+ .cantunwind
+ .fnend
diff --git a/support/ld/libcs3_stm32_src/start_c.c b/support/ld/libcs3_stm32_src/start_c.c new file mode 100644 index 0000000..dff9fa3 --- /dev/null +++ b/support/ld/libcs3_stm32_src/start_c.c @@ -0,0 +1,58 @@ +/* CS3 start_c routine.
+ *
+ * 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 "cs3.h"
+
+extern void __libc_init_array (void);
+
+extern int main (int, char **, char **);
+
+extern void exit (int) __attribute__ ((noreturn, weak));
+
+void __attribute ((noreturn))
+__cs3_start_c (void)
+{
+ unsigned regions = __cs3_region_num;
+ const struct __cs3_region *rptr = __cs3_regions;
+ int exit_code;
+
+ /* Initialize memory */
+ for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++)
+ {
+ long long *src = (long long *)rptr->init;
+ long long *dst = (long long *)rptr->data;
+ unsigned limit = rptr->init_size;
+ unsigned count;
+
+ if (src != dst)
+ for (count = 0; count != limit; count += sizeof (long long))
+ *dst++ = *src++;
+ else
+ dst = (long long *)((char *)dst + limit);
+ limit = rptr->zero_size;
+ for (count = 0; count != limit; count += sizeof (long long))
+ *dst++ = 0;
+ }
+
+ /* Run initializers. */
+ __libc_init_array ();
+
+ exit_code = main (0, NULL, NULL);
+ if (exit)
+ exit (exit_code);
+ /* If exit is NULL, make sure we don't return. */
+ for (;;)
+ continue;
+}
diff --git a/support/ld/libcs3_stm32_src/stm32_isrs.S b/support/ld/libcs3_stm32_src/stm32_isrs.S new file mode 100644 index 0000000..f95468c --- /dev/null +++ b/support/ld/libcs3_stm32_src/stm32_isrs.S @@ -0,0 +1,235 @@ +/* STM32 ISR weak declarations */
+
+ .thumb
+
+/* Default handler for all non-overridden interrupts and exceptions */
+ .globl __default_handler
+ .type __default_handler, %function
+
+__default_handler:
+ b .
+
+ .weak __exc_nmi
+ .globl __exc_nmi
+ .set __exc_nmi, __default_handler
+ .weak __exc_hardfault
+ .globl __exc_hardfault
+ .set __exc_hardfault, __default_handler
+ .weak __exc_memmanage
+ .globl __exc_memmanage
+ .set __exc_memmanage, __default_handler
+ .weak __exc_busfault
+ .globl __exc_busfault
+ .set __exc_busfault, __default_handler
+ .weak __exc_usagefault
+ .globl __exc_usagefault
+ .set __exc_usagefault, __default_handler
+ .weak __stm32reservedexception7
+ .globl __stm32reservedexception7
+ .set __stm32reservedexception7, __default_handler
+ .weak __stm32reservedexception8
+ .globl __stm32reservedexception8
+ .set __stm32reservedexception8, __default_handler
+ .weak __stm32reservedexception9
+ .globl __stm32reservedexception9
+ .set __stm32reservedexception9, __default_handler
+ .weak __stm32reservedexception10
+ .globl __stm32reservedexception10
+ .set __stm32reservedexception10, __default_handler
+ .weak __exc_svc
+ .globl __exc_svc
+ .set __exc_svc, __default_handler
+ .weak __exc_debug_monitor
+ .globl __exc_debug_monitor
+ .set __exc_debug_monitor, __default_handler
+ .weak __stm32reservedexception13
+ .globl __stm32reservedexception13
+ .set __stm32reservedexception13, __default_handler
+ .weak __exc_pendsv
+ .globl __exc_pendsv
+ .set __exc_pendsv, __default_handler
+ .weak __exc_systick
+ .globl __exc_systick
+ .set __exc_systick, __default_handler
+ .weak __irq_wwdg
+ .globl __irq_wwdg
+ .set __irq_wwdg, __default_handler
+ .weak __irq_pvd
+ .globl __irq_pvd
+ .set __irq_pvd, __default_handler
+ .weak __irq_tamper
+ .globl __irq_tamper
+ .set __irq_tamper, __default_handler
+ .weak __irq_rtc
+ .globl __irq_rtc
+ .set __irq_rtc, __default_handler
+ .weak __irq_flash
+ .globl __irq_flash
+ .set __irq_flash, __default_handler
+ .weak __irq_rcc
+ .globl __irq_rcc
+ .set __irq_rcc, __default_handler
+ .weak __irq_exti0
+ .globl __irq_exti0
+ .set __irq_exti0, __default_handler
+ .weak __irq_exti1
+ .globl __irq_exti1
+ .set __irq_exti1, __default_handler
+ .weak __irq_exti2
+ .globl __irq_exti2
+ .set __irq_exti2, __default_handler
+ .weak __irq_exti3
+ .globl __irq_exti3
+ .set __irq_exti3, __default_handler
+ .weak __irq_exti4
+ .globl __irq_exti4
+ .set __irq_exti4, __default_handler
+ .weak __irq_dma1_channel1
+ .globl __irq_dma1_channel1
+ .set __irq_dma1_channel1, __default_handler
+ .weak __irq_dma1_channel2
+ .globl __irq_dma1_channel2
+ .set __irq_dma1_channel2, __default_handler
+ .weak __irq_dma1_channel3
+ .globl __irq_dma1_channel3
+ .set __irq_dma1_channel3, __default_handler
+ .weak __irq_dma1_channel4
+ .globl __irq_dma1_channel4
+ .set __irq_dma1_channel4, __default_handler
+ .weak __irq_dma1_channel5
+ .globl __irq_dma1_channel5
+ .set __irq_dma1_channel5, __default_handler
+ .weak __irq_dma1_channel6
+ .globl __irq_dma1_channel6
+ .set __irq_dma1_channel6, __default_handler
+ .weak __irq_dma1_channel7
+ .globl __irq_dma1_channel7
+ .set __irq_dma1_channel7, __default_handler
+ .weak __irq_adc
+ .globl __irq_adc
+ .set __irq_adc, __default_handler
+ .weak __irq_usb_hp_can_tx
+ .globl __irq_usb_hp_can_tx
+ .set __irq_usb_hp_can_tx, __default_handler
+ .weak __irq_usb_lp_can_rx0
+ .globl __irq_usb_lp_can_rx0
+ .set __irq_usb_lp_can_rx0, __default_handler
+ .weak __irq_can_rx1
+ .globl __irq_can_rx1
+ .set __irq_can_rx1, __default_handler
+ .weak __irq_can_sce
+ .globl __irq_can_sce
+ .set __irq_can_sce, __default_handler
+ .weak __irq_exti9_5
+ .globl __irq_exti9_5
+ .set __irq_exti9_5, __default_handler
+ .weak __irq_tim1_brk
+ .globl __irq_tim1_brk
+ .set __irq_tim1_brk, __default_handler
+ .weak __irq_tim1_up
+ .globl __irq_tim1_up
+ .set __irq_tim1_up, __default_handler
+ .weak __irq_tim1_trg_com
+ .globl __irq_tim1_trg_com
+ .set __irq_tim1_trg_com, __default_handler
+ .weak __irq_tim1_cc
+ .globl __irq_tim1_cc
+ .set __irq_tim1_cc, __default_handler
+ .weak __irq_tim2
+ .globl __irq_tim2
+ .set __irq_tim2, __default_handler
+ .weak __irq_tim3
+ .globl __irq_tim3
+ .set __irq_tim3, __default_handler
+ .weak __irq_tim4
+ .globl __irq_tim4
+ .set __irq_tim4, __default_handler
+ .weak __irq_i2c1_ev
+ .globl __irq_i2c1_ev
+ .set __irq_i2c1_ev, __default_handler
+ .weak __irq_i2c1_er
+ .globl __irq_i2c1_er
+ .set __irq_i2c1_er, __default_handler
+ .weak __irq_i2c2_ev
+ .globl __irq_i2c2_ev
+ .set __irq_i2c2_ev, __default_handler
+ .weak __irq_i2c2_er
+ .globl __irq_i2c2_er
+ .set __irq_i2c2_er, __default_handler
+ .weak __irq_spi1
+ .globl __irq_spi1
+ .set __irq_spi1, __default_handler
+ .weak __irq_spi2
+ .globl __irq_spi2
+ .set __irq_spi2, __default_handler
+ .weak __irq_usart1
+ .globl __irq_usart1
+ .set __irq_usart1, __default_handler
+ .weak __irq_usart2
+ .globl __irq_usart2
+ .set __irq_usart2, __default_handler
+ .weak __irq_usart3
+ .globl __irq_usart3
+ .set __irq_usart3, __default_handler
+ .weak __irq_exti15_10
+ .globl __irq_exti15_10
+ .set __irq_exti15_10, __default_handler
+ .weak __irq_rtcalarm
+ .globl __irq_rtcalarm
+ .set __irq_rtcalarm, __default_handler
+ .weak __irq_usbwakeup
+ .globl __irq_usbwakeup
+ .set __irq_usbwakeup, __default_handler
+#if defined (STM32_HIGH_DENSITY)
+ .weak __irq_tim8_brk
+ .globl __irq_tim8_brk
+ .set __irq_tim8_brk, __default_handler
+ .weak __irq_tim8_up
+ .globl __irq_tim8_up
+ .set __irq_tim8_up, __default_handler
+ .weak __irq_tim8_trg_com
+ .globl __irq_tim8_trg_com
+ .set __irq_tim8_trg_com, __default_handler
+ .weak __irq_tim8_cc
+ .globl __irq_tim8_cc
+ .set __irq_tim8_cc, __default_handler
+ .weak __irq_adc3
+ .globl __irq_adc3
+ .set __irq_adc3, __default_handler
+ .weak __irq_fsmc
+ .globl __irq_fsmc
+ .set __irq_fsmc, __default_handler
+ .weak __irq_sdio
+ .globl __irq_sdio
+ .set __irq_sdio, __default_handler
+ .weak __irq_tim5
+ .globl __irq_tim5
+ .set __irq_tim5, __default_handler
+ .weak __irq_spi3
+ .globl __irq_spi3
+ .set __irq_spi3, __default_handler
+ .weak __irq_uart4
+ .globl __irq_uart4
+ .set __irq_uart4, __default_handler
+ .weak __irq_uart5
+ .globl __irq_uart5
+ .set __irq_uart5, __default_handler
+ .weak __irq_tim6
+ .globl __irq_tim6
+ .set __irq_tim6, __default_handler
+ .weak __irq_tim7
+ .globl __irq_tim7
+ .set __irq_tim7, __default_handler
+ .weak __irq_dma2_channel1
+ .globl __irq_dma2_channel1
+ .set __irq_dma2_channel1, __default_handler
+ .weak __irq_dma2_channel2
+ .globl __irq_dma2_channel2
+ .set __irq_dma2_channel2, __default_handler
+ .weak __irq_dma2_channel3
+ .globl __irq_dma2_channel3
+ .set __irq_dma2_channel3, __default_handler
+ .weak __irq_dma2_channel4_5
+ .globl __irq_dma2_channel4_5
+ .set __irq_dma2_channel4_5, __default_handler
+#endif /* STM32_HIGH_DENSITY */
diff --git a/support/ld/libcs3_stm32_src/stm32_vector_table.S b/support/ld/libcs3_stm32_src/stm32_vector_table.S new file mode 100644 index 0000000..8c71cb5 --- /dev/null +++ b/support/ld/libcs3_stm32_src/stm32_vector_table.S @@ -0,0 +1,90 @@ +/* STM32 vector table */
+
+ .section ".cs3.interrupt_vector"
+
+ .globl __cs3_stm32_vector_table
+ .type __cs3_stm32_vector_table, %object
+
+__cs3_stm32_vector_table:
+/* CM3 core interrupts */
+ .long __cs3_stack
+ .long __cs3_reset
+ .long __exc_nmi
+ .long __exc_hardfault
+ .long __exc_memmanage
+ .long __exc_busfault
+ .long __exc_usagefault
+ .long __stm32reservedexception7
+ .long __stm32reservedexception8
+ .long __stm32reservedexception9
+ .long __stm32reservedexception10
+ .long __exc_svc
+ .long __exc_debug_monitor
+ .long __stm32reservedexception13
+ .long __exc_pendsv
+ .long __exc_systick
+/* Peripheral interrupts */
+ .long __irq_wwdg
+ .long __irq_pvd
+ .long __irq_tamper
+ .long __irq_rtc
+ .long __irq_flash
+ .long __irq_rcc
+ .long __irq_exti0
+ .long __irq_exti1
+ .long __irq_exti2
+ .long __irq_exti3
+ .long __irq_exti4
+ .long __irq_dma1_channel1
+ .long __irq_dma1_channel2
+ .long __irq_dma1_channel3
+ .long __irq_dma1_channel4
+ .long __irq_dma1_channel5
+ .long __irq_dma1_channel6
+ .long __irq_dma1_channel7
+ .long __irq_adc
+ .long __irq_usb_hp_can_tx
+ .long __irq_usb_lp_can_rx0
+ .long __irq_can_rx1
+ .long __irq_can_sce
+ .long __irq_exti9_5
+ .long __irq_tim1_brk
+ .long __irq_tim1_up
+ .long __irq_tim1_trg_com
+ .long __irq_tim1_cc
+ .long __irq_tim2
+ .long __irq_tim3
+ .long __irq_tim4
+ .long __irq_i2c1_ev
+ .long __irq_i2c1_er
+ .long __irq_i2c2_ev
+ .long __irq_i2c2_er
+ .long __irq_spi1
+ .long __irq_spi2
+ .long __irq_usart1
+ .long __irq_usart2
+ .long __irq_usart3
+ .long __irq_exti15_10
+ .long __irq_rtcalarm
+ .long __irq_usbwakeup
+#if defined (STM32_HIGH_DENSITY)
+ .weak __irq_tim8_brk
+ .weak __irq_tim8_up
+ .weak __irq_tim8_trg_com
+ .weak __irq_tim8_cc
+ .weak __irq_adc3
+ .weak __irq_fsmc
+ .weak __irq_sdio
+ .weak __irq_tim5
+ .weak __irq_spi3
+ .weak __irq_uart4
+ .weak __irq_uart5
+ .weak __irq_tim6
+ .weak __irq_tim7
+ .weak __irq_dma2_channel1
+ .weak __irq_dma2_channel2
+ .weak __irq_dma2_channel3
+ .weak __irq_dma2_channel4_5
+#endif /* STM32_HIGH_DENSITY */
+
+ .size __cs3_stm32_vector_table, . - __cs3_stm32_vector_table
diff --git a/support/ld/maple/flash.ld b/support/ld/maple/flash.ld index 2d40100..9c3efcb 100644 --- a/support/ld/maple/flash.ld +++ b/support/ld/maple/flash.ld @@ -1,211 +1,28 @@ -/* Linker script for STM32 (by Lanchon with Mods by LeafLabs)
- *
- * Version:Sourcery G++ 4.2-84
- * BugURL:https://support.codesourcery.com/GNUToolchain/
- *
- * Copyright 2007 CodeSourcery.
- *
- * 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. */
-
-/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
+/*
+ * Linker script for STM32.
+ * STM32F103RBT6 medium density chip linker script for use with
+ * maple bootloader. Loads to flash.
+ */
-/* Define memory spaces. */
+/*
+ * Define memory spaces.
+ */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K
}
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use medium density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
- *(.rom)
- *(.rom.b)
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.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 = .;
+GROUP(libcs3_stm32_med_density.a)
- . = ALIGN(4);
- __init_array_start = .;
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- __init_array_end = .;
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >rom
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >rom
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >rom
-
-/* expose a custom rom only section */
- .USER_FLASH :
- {
- *(.USER_FLASH)
- } >rom
-
-
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom);
- __cs3_region_size_rom = LENGTH(rom);
- __cs3_region_num = 1;
-
- .data :
- {
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram AT>rom
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram AT>rom
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.data);
- __cs3_region_init_size_ram = _edata - ADDR (.data);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
-}
+/*
+ * Define the rest of the sections
+ */
+INCLUDE common_rom.inc
diff --git a/support/ld/maple/jtag.ld b/support/ld/maple/jtag.ld index 435e3f0..caf90ee 100644 --- a/support/ld/maple/jtag.ld +++ b/support/ld/maple/jtag.ld @@ -1,186 +1,28 @@ -/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
+/*
+ * Linker script for STM32.
+ * STM32F103RBT6 medium density chip linker script.
+ */
-/* Define memory spaces. */
+/*
+ * Define memory spaces.
+ */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
}
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use medium density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
- *(.rom)
- *(.rom.b)
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.ARM.extab* .gnu.linkonce.armextab.*)
- *(.gcc_except_table)
- *(.eh_frame_hdr)
- *(.eh_frame)
-
- . = ALIGN(4);
- KEEP(*(.init))
+GROUP(libcs3_stm32_med_density.a)
- . = ALIGN(4);
- __preinit_array_start = .;
- KEEP (*(.preinit_array))
- __preinit_array_end = .;
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >rom
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >rom
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >rom
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom);
- __cs3_region_size_rom = LENGTH(rom);
- __cs3_region_num = 1;
-
- .data :
- {
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram AT>rom
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram AT>rom
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.data);
- __cs3_region_init_size_ram = _edata - ADDR (.data);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
+/*
+ * Define the rest of the sections
+ */
+INCLUDE common_rom.inc
- .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
- .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
diff --git a/support/ld/maple/ram.ld b/support/ld/maple/ram.ld index 1fbecc5..b1e285e 100644 --- a/support/ld/maple/ram.ld +++ b/support/ld/maple/ram.ld @@ -1,220 +1,27 @@ -/* Linker script for STM32 (by Lanchon with Mods by LeafLabs)
- *
- * Version:Sourcery G++ 4.2-84
- * BugURL:https://support.codesourcery.com/GNUToolchain/
- *
- * Copyright 2007 CodeSourcery.
- *
- * 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. */
-
-/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
+/*
+ * Linker script for STM32.
+ * STM32F103RBT6 medium density chip linker script. Loads to ram.
+ */
-/* Define memory spaces. */
+/*
+ * Define memory spaces.
+ */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
}
-
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use medium density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.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 = .;
+GROUP(libcs3_stm32_med_density.a)
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >ram
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- /* even cs3.rom is in ram since its running as user code under the Maple
- bootloader */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >ram
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >ram
-
- .cs3.rom :
- {
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- *(.rom)
- . = ALIGN (8);
- } >ram
-
- .cs3.rom.bss :
- {
- *(.rom.b)
- . = ALIGN (8);
- } >ram
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(ram);
- __cs3_region_size_rom = LENGTH(ram);
- __cs3_region_init_rom = LOADADDR (.cs3.rom);
- __cs3_region_init_size_rom = SIZEOF(.cs3.rom);
- __cs3_region_zero_size_rom = SIZEOF(.cs3.rom.bss);
-
- .data :
- {
-
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.text);
- __cs3_region_init_size_ram = _edata - ADDR (.text);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
-}
+REGION_ALIAS("REGION_TEXT", ram);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+/*
+ * Define the rest of the sections
+ */
+INCLUDE common_ram.inc
diff --git a/support/ld/maple_mini/flash.ld b/support/ld/maple_mini/flash.ld index 2d40100..4c26da2 100644 --- a/support/ld/maple_mini/flash.ld +++ b/support/ld/maple_mini/flash.ld @@ -1,211 +1,27 @@ -/* Linker script for STM32 (by Lanchon with Mods by LeafLabs)
- *
- * Version:Sourcery G++ 4.2-84
- * BugURL:https://support.codesourcery.com/GNUToolchain/
- *
- * Copyright 2007 CodeSourcery.
- *
- * 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. */
-
-/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
+/*
+ * Linker script for STM32.
+ * Maple mini flash linker script.
+ */
-/* Define memory spaces. */
+/*
+ * Define memory spaces.
+ */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K
}
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use medium density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
- *(.rom)
- *(.rom.b)
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.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 = .;
+GROUP(libcs3_stm32_med_density.a)
- . = ALIGN(4);
- __init_array_start = .;
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- __init_array_end = .;
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >rom
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >rom
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >rom
-
-/* expose a custom rom only section */
- .USER_FLASH :
- {
- *(.USER_FLASH)
- } >rom
-
-
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom);
- __cs3_region_size_rom = LENGTH(rom);
- __cs3_region_num = 1;
-
- .data :
- {
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram AT>rom
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram AT>rom
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.data);
- __cs3_region_init_size_ram = _edata - ADDR (.data);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
-}
+/*
+ * Define the rest of the sections
+ */
+INCLUDE common_rom.inc
diff --git a/support/ld/maple_mini/jtag.ld b/support/ld/maple_mini/jtag.ld index 435e3f0..31768ed 100644 --- a/support/ld/maple_mini/jtag.ld +++ b/support/ld/maple_mini/jtag.ld @@ -1,186 +1,28 @@ -/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
+/*
+ * Linker script for STM32.
+ * Maple mini linker script bare metal target linker script.
+ */
-/* Define memory spaces. */
+/*
+ * Define memory spaces.
+ */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
}
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use medium density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
- *(.rom)
- *(.rom.b)
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.ARM.extab* .gnu.linkonce.armextab.*)
- *(.gcc_except_table)
- *(.eh_frame_hdr)
- *(.eh_frame)
-
- . = ALIGN(4);
- KEEP(*(.init))
+GROUP(libcs3_stm32_med_density.a)
- . = ALIGN(4);
- __preinit_array_start = .;
- KEEP (*(.preinit_array))
- __preinit_array_end = .;
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >rom
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >rom
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >rom
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom);
- __cs3_region_size_rom = LENGTH(rom);
- __cs3_region_num = 1;
-
- .data :
- {
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram AT>rom
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram AT>rom
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.data);
- __cs3_region_init_size_ram = _edata - ADDR (.data);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
+/*
+ * Define the rest of the sections
+ */
+INCLUDE common_rom.inc
- .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
- .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
diff --git a/support/ld/maple_mini/ram.ld b/support/ld/maple_mini/ram.ld index 1fbecc5..7dd7ee5 100644 --- a/support/ld/maple_mini/ram.ld +++ b/support/ld/maple_mini/ram.ld @@ -1,220 +1,27 @@ -/* Linker script for STM32 (by Lanchon with Mods by LeafLabs)
- *
- * Version:Sourcery G++ 4.2-84
- * BugURL:https://support.codesourcery.com/GNUToolchain/
- *
- * Copyright 2007 CodeSourcery.
- *
- * 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. */
-
-/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
+/*
+ * Linker script for STM32.
+ * Maple mini ram target linker script.
+ */
-/* Define memory spaces. */
+/*
+ * Define memory spaces.
+ */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
}
-
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use medium density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.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 = .;
+GROUP(libcs3_stm32_med_density.a)
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >ram
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- /* even cs3.rom is in ram since its running as user code under the Maple
- bootloader */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >ram
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >ram
-
- .cs3.rom :
- {
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- *(.rom)
- . = ALIGN (8);
- } >ram
-
- .cs3.rom.bss :
- {
- *(.rom.b)
- . = ALIGN (8);
- } >ram
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(ram);
- __cs3_region_size_rom = LENGTH(ram);
- __cs3_region_init_rom = LOADADDR (.cs3.rom);
- __cs3_region_init_size_rom = SIZEOF(.cs3.rom);
- __cs3_region_zero_size_rom = SIZEOF(.cs3.rom.bss);
-
- .data :
- {
-
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.text);
- __cs3_region_init_size_ram = _edata - ADDR (.text);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
-}
+REGION_ALIAS("REGION_TEXT", ram);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
+/*
+ * Define the rest of the sections
+ */
+INCLUDE common_ram.inc
diff --git a/support/ld/maple_native/flash.ld b/support/ld/maple_native/flash.ld index 4e820d2..4358419 100644 --- a/support/ld/maple_native/flash.ld +++ b/support/ld/maple_native/flash.ld @@ -1,211 +1,22 @@ -/* Linker script for STM32 (by Lanchon with Mods by LeafLabs)
- *
- * Version:Sourcery G++ 4.2-84
- * BugURL:https://support.codesourcery.com/GNUToolchain/
- *
- * Copyright 2007 CodeSourcery.
- *
- * 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. */
-
-/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
+/*
+ * Linker script for STM32.
+ * STM32 high density chip linker script. Loads to flash with Maple bootloader
+ */
-/* Define memory spaces. */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K
}
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use high density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
- *(.rom)
- *(.rom.b)
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.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 = .;
+GROUP(libcs3_stm32_high_density.a)
- . = ALIGN(4);
- __init_array_start = .;
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- __init_array_end = .;
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
- . = ALIGN(0x4);
- KEEP (*crtbegin.o(.ctors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*crtend.o(.ctors))
+INCLUDE common_rom.inc
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >rom
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >rom
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >rom
-
-/* expose a custom rom only section */
- .USER_FLASH :
- {
- *(.USER_FLASH)
- } >rom
-
-
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom);
- __cs3_region_size_rom = LENGTH(rom);
- __cs3_region_num = 1;
-
- .data :
- {
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram AT>rom
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram AT>rom
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.data);
- __cs3_region_init_size_ram = _edata - ADDR (.data);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
-}
diff --git a/support/ld/maple_native/jtag.ld b/support/ld/maple_native/jtag.ld index 90a0a3f..0e99c3b 100644 --- a/support/ld/maple_native/jtag.ld +++ b/support/ld/maple_native/jtag.ld @@ -1,186 +1,21 @@ -/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
-
-/* Define memory spaces. */
+/*
+ * Linker script for STM32.
+ * STM32 high density chip linker script. Bare metal linker script.
+ */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use high density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
- *(.rom)
- *(.rom.b)
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.ARM.extab* .gnu.linkonce.armextab.*)
- *(.gcc_except_table)
- *(.eh_frame_hdr)
- *(.eh_frame)
+GROUP(libcs3_stm32_high_density.a)
- . = ALIGN(4);
- KEEP(*(.init))
+REGION_ALIAS("REGION_TEXT", rom);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
- . = ALIGN(4);
- __preinit_array_start = .;
- KEEP (*(.preinit_array))
- __preinit_array_end = .;
+INCLUDE common_rom.inc
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >rom
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >rom
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >rom
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom);
- __cs3_region_size_rom = LENGTH(rom);
- __cs3_region_num = 1;
-
- .data :
- {
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram AT>rom
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram AT>rom
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.data);
- __cs3_region_init_size_ram = _edata - ADDR (.data);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
-}
diff --git a/support/ld/maple_native/ram.ld b/support/ld/maple_native/ram.ld index a5e1482..22c09cd 100644 --- a/support/ld/maple_native/ram.ld +++ b/support/ld/maple_native/ram.ld @@ -1,220 +1,22 @@ -/* Linker script for STM32 (by Lanchon with Mods by LeafLabs)
- *
- * Version:Sourcery G++ 4.2-84
- * BugURL:https://support.codesourcery.com/GNUToolchain/
- *
- * Copyright 2007 CodeSourcery.
- *
- * 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. */
-
-/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
+/*
+ * Linker script for STM32.
+ * STM32 high density chip linker script. Loads to RAM with Maple bootloader
+ */
-/* Define memory spaces. */
MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
}
-
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
+/*
+ * Use high density device vector table
*/
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.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 = .;
+GROUP(libcs3_stm32_high_density.a)
- . = ALIGN(4);
- __init_array_start = .;
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- __init_array_end = .;
+REGION_ALIAS("REGION_TEXT", ram);
+REGION_ALIAS("REGION_DATA", ram);
+REGION_ALIAS("REGION_BSS", ram);
- . = 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))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >ram
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- /* even cs3.rom is in ram since its running as user code under the Maple
- bootloader */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >ram
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >ram
-
- .cs3.rom :
- {
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- *(.rom)
- . = ALIGN (8);
- } >ram
-
- .cs3.rom.bss :
- {
- *(.rom.b)
- . = ALIGN (8);
- } >ram
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(ram);
- __cs3_region_size_rom = LENGTH(ram);
- __cs3_region_init_rom = LOADADDR (.cs3.rom);
- __cs3_region_init_size_rom = SIZEOF(.cs3.rom);
- __cs3_region_zero_size_rom = SIZEOF(.cs3.rom.bss);
-
- .data :
- {
-
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.text);
- __cs3_region_init_size_ram = _edata - ADDR (.text);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .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) }
-}
+INCLUDE common_ram.inc
diff --git a/support/ld/names.inc b/support/ld/names.inc index bb65dcd..9fab36c 100644 --- a/support/ld/names.inc +++ b/support/ld/names.inc @@ -1,61 +1,78 @@ -/* ISR names for STM32 (by Lanchon) */
+EXTERN(__cs3_stack)
+EXTERN(__cs3_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 (__cs3_stack)
-EXTERN (__cs3_reset)
-EXTERN (NMIException)
-EXTERN (HardFaultException)
-EXTERN (MemManageException)
-EXTERN (BusFaultException)
-EXTERN (UsageFaultException)
-EXTERN (__STM32ReservedException7)
-EXTERN (__STM32ReservedException8)
-EXTERN (__STM32ReservedException9)
-EXTERN (__STM32ReservedException10)
-EXTERN (SVCHandler)
-EXTERN (DebugMonitor)
-EXTERN (__STM32ReservedException13)
-EXTERN (PendSVC)
-EXTERN (SysTickHandler)
-EXTERN (WWDG_IRQHandler)
-EXTERN (PVD_IRQHandler)
-EXTERN (TAMPER_IRQHandler)
-EXTERN (RTC_IRQHandler)
-EXTERN (FLASH_IRQHandler)
-EXTERN (RCC_IRQHandler)
-EXTERN (EXTI0_IRQHandler)
-EXTERN (EXTI1_IRQHandler)
-EXTERN (EXTI2_IRQHandler)
-EXTERN (EXTI3_IRQHandler)
-EXTERN (EXTI4_IRQHandler)
-EXTERN (DMAChannel1_IRQHandler)
-EXTERN (DMAChannel2_IRQHandler)
-EXTERN (DMAChannel3_IRQHandler)
-EXTERN (DMAChannel4_IRQHandler)
-EXTERN (DMAChannel5_IRQHandler)
-EXTERN (DMAChannel6_IRQHandler)
-EXTERN (DMAChannel7_IRQHandler)
-EXTERN (ADC_IRQHandler)
-EXTERN (USB_HP_CAN_TX_IRQHandler)
-EXTERN (USB_LP_CAN_RX0_IRQHandler)
-EXTERN (CAN_RX1_IRQHandler)
-EXTERN (CAN_SCE_IRQHandler)
-EXTERN (EXTI9_5_IRQHandler)
-EXTERN (TIM1_BRK_IRQHandler)
-EXTERN (TIM1_UP_IRQHandler)
-EXTERN (TIM1_TRG_COM_IRQHandler)
-EXTERN (TIM1_CC_IRQHandler)
-EXTERN (TIM2_IRQHandler)
-EXTERN (TIM3_IRQHandler)
-EXTERN (TIM4_IRQHandler)
-EXTERN (i2c1_ev_irq_handler)
-EXTERN (i2c1_er_irq_handler)
-EXTERN (i2c2_ev_irq_handler)
-EXTERN (i2c2_er_irq_handler)
-EXTERN (SPI1_IRQHandler)
-EXTERN (SPI2_IRQHandler)
-EXTERN (USART1_IRQHandler)
-EXTERN (USART2_IRQHandler)
-EXTERN (USART3_IRQHandler)
-EXTERN (EXTI15_10_IRQHandler)
-EXTERN (RTCAlarm_IRQHandler)
-EXTERN (USBWakeUp_IRQHandler)
+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_dma_channel1)
+EXTERN(__irq_dma_channel2)
+EXTERN(__irq_dma_channel3)
+EXTERN(__irq_dma_channel4)
+EXTERN(__irq_dma_channel5)
+EXTERN(__irq_dma_channel6)
+EXTERN(__irq_dma_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)
diff --git a/support/ld/src.zip b/support/ld/src.zip Binary files differdeleted file mode 100644 index 58ff908..0000000 --- a/support/ld/src.zip +++ /dev/null diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp index 354663e..0f8bec6 100644 --- a/wirish/HardwareTimer.cpp +++ b/wirish/HardwareTimer.cpp @@ -199,7 +199,7 @@ HardwareTimer Timer1(TIMER1); HardwareTimer Timer2(TIMER2); HardwareTimer Timer3(TIMER3); HardwareTimer Timer4(TIMER4); -#if NR_TIMERS >= 8 +#ifdef STM32_HIGH_DENSITY HardwareTimer Timer5(TIMER5); // High-density devices only HardwareTimer Timer8(TIMER8); // High-density devices only #endif @@ -214,7 +214,7 @@ HardwareTimer* getTimer(timer_dev_num timerNum) { return &Timer3; case TIMER4: return &Timer4; -#if NR_TIMERS >= 8 +#ifdef STM32_HIGH_DENSITY case TIMER5: return &Timer5; case TIMER8: diff --git a/wirish/HardwareTimer.h b/wirish/HardwareTimer.h index 4034b1f..4030adc 100644 --- a/wirish/HardwareTimer.h +++ b/wirish/HardwareTimer.h @@ -382,7 +382,7 @@ extern HardwareTimer Timer2; extern HardwareTimer Timer3; /** Pre-instantiated timer for use by user code. */ extern HardwareTimer Timer4; -#if NR_TIMERS >= 8 +#ifdef STM32_HIGH_DENSITY /** Pre-instantiated timer for use by user code, on devices with more than four timers (this does not include the Maple). */ extern HardwareTimer Timer5; diff --git a/wirish/boards.h b/wirish/boards.h index f8505ab..989eea1 100644 --- a/wirish/boards.h +++ b/wirish/boards.h @@ -51,18 +51,13 @@ enum { D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105, D106, D107, D108, D109, D110, D111, }; -/* Set of all possible analog pin names; not all boards have all these */ -enum { - ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, ADC10, ADC11, - ADC12, ADC13, ADC14, ADC15, ADC16, ADC17, ADC18, ADC19, ADC20, }; - #define ADC_INVALID 0xFFFFFFFF /* Types used for the tables below */ typedef struct PinMapping { GPIO_Port *port; uint32 pin; - uint32 adc; + uint32 adc_channel; TimerCCR timer_ccr; uint32 exti_port; timer_dev_num timer_num; @@ -75,94 +70,98 @@ typedef struct PinMapping { #define CYCLES_PER_MICROSECOND 72 #define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ - #define BOARD_BUTTON_PIN 38 - #define BOARD_LED_PIN 13 + #define BOARD_BUTTON_PIN 38 + #define BOARD_LED_PIN 13 + + /* Total number of GPIO pins that are broken out to headers and + intended for general use. */ + #define NR_GPIO_PINS 39 static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { /* D0/PA3 */ - {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, + {GPIOA_BASE, 3, 3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, /* D1/PA2 */ - {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, + {GPIOA_BASE, 2, 2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, /* D2/PA0 */ - {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1}, + {GPIOA_BASE, 0, 0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1}, /* D3/PA1 */ - {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, + {GPIOA_BASE, 1, 1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, /* D4/PB5 */ - {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D5/PB6 */ - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, /* D6/PA8 */ - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA, TIMER1, 1}, + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA, TIMER1, 1}, /* D7/PA9 */ - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER1, 2}, + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER1, 2}, /* D8/PA10 */ - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, /* D9/PB7 */ - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2}, + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2}, /* D10/PA4 */ - {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + {GPIOA_BASE, 4, 4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, /* D11/PA7 */ - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, + {GPIOA_BASE, 7, 7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, /* D12/PA6 */ - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, + {GPIOA_BASE, 6, 6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, /* D13/PA5 */ - {GPIOA_BASE, 5, ADC5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + {GPIOA_BASE, 5, 5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, /* D14/PB8 */ - {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB, TIMER4, 3}, + {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB, TIMER4, 3}, /* Little header */ /* D15/PC0 */ - {GPIOC_BASE, 0, ADC10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 0, 10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D16/PC1 */ - {GPIOC_BASE, 1, ADC11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 1, 11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D17/PC2 */ - {GPIOC_BASE, 2, ADC12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 2, 12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D18/PC3 */ - {GPIOC_BASE, 3, ADC13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 3, 13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D19/PC4 */ - {GPIOC_BASE, 4, ADC14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 4, 14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D20/PC5 */ - {GPIOC_BASE, 5, ADC15, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 5, 15, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* External header */ /* D21/PC13 */ - {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D22/PC14 */ - {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D23/PC15 */ - {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D24/PB9 */ - {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D25/PD2 */ - {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D26/PC10 */ - {GPIOC_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D27/PB0 */ - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, + {GPIOB_BASE, 0, 8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, /* D28/PB1 */ - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, + {GPIOB_BASE, 1, 9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, /* D29/PB10 */ - {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D30/PB11 */ - {GPIOB_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D31/PB12 */ - {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D32/PB13 */ - {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D33/PB14 */ - {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D34/PB15 */ - {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D35/PC6 */ - {GPIOC_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D36/PC7 */ - {GPIOC_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D37/PC8 */ - {GPIOC_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D38/PC9 (BUT) */ - {GPIOC_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID} + {GPIOC_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID} }; #define BOARD_INIT do { \ @@ -178,216 +177,218 @@ typedef struct PinMapping { #define BOARD_LED_PIN D21 #define BOARD_BUTTON_PIN D18 + #define NR_GPIO_PINS 100 + static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { /* Top header */ /* D0/PB10 */ - {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D1/PB2 */ - {GPIOB_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D2/PB12 */ - {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D3/PB13 */ - {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D4/PB14 */ - {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D5/PB15 */ - {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D6/PC0 */ - {GPIOC_BASE, 0, ADC10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 0, 10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D7/PC1 */ - {GPIOC_BASE, 1, ADC11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 1, 11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D8/PC2 */ - {GPIOC_BASE, 2, ADC12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 2, 12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D9/PC3 */ - {GPIOC_BASE, 3, ADC13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 3, 13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D10/PC4 */ - {GPIOC_BASE, 4, ADC14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 4, 14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D11/PC5 */ - {GPIOC_BASE, 5, ADC15, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 5, 15, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D12/PC6 */ - {GPIOC_BASE, 6, ADC_INVALID, TIMER8_CH1_CCR, EXTI_CONFIG_PORTC, TIMER8, 1}, + {GPIOC_BASE, 6, ADC_INVALID, TIMER8_CH1_CCR, EXTI_CONFIG_PORTC, TIMER8, 1}, /* D13/PC7 */ - {GPIOC_BASE, 7, ADC_INVALID, TIMER8_CH2_CCR, EXTI_CONFIG_PORTC, TIMER8, 2}, + {GPIOC_BASE, 7, ADC_INVALID, TIMER8_CH2_CCR, EXTI_CONFIG_PORTC, TIMER8, 2}, /* D14/PC8 */ - {GPIOC_BASE, 8, ADC_INVALID, TIMER8_CH3_CCR, EXTI_CONFIG_PORTC, TIMER8, 3}, + {GPIOC_BASE, 8, ADC_INVALID, TIMER8_CH3_CCR, EXTI_CONFIG_PORTC, TIMER8, 3}, /* D15/PC9 */ - {GPIOC_BASE, 9, ADC_INVALID, TIMER8_CH4_CCR, EXTI_CONFIG_PORTC, TIMER8, 4}, + {GPIOC_BASE, 9, ADC_INVALID, TIMER8_CH4_CCR, EXTI_CONFIG_PORTC, TIMER8, 4}, /* D16/PC10 */ - {GPIOC_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D17/PC11 */ - {GPIOC_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D18/PC12 */ - {GPIOC_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D19/PC13 */ - {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D20/PC14 */ - {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D21/PC15 */ - {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, + {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D22/PA8 */ - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA, TIMER1, 1}, + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA, TIMER1, 1}, /* D23/PA9 */ - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER1, 2}, + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER1, 2}, /* D24/PA10 */ - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, /* D25/PB9 */ - {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER4, 4}, + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER4, 4}, /* Bottom header */ /* D26/PD2 */ - {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D27/PD3 */ - {GPIOD_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D28/PD6 */ - {GPIOD_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D29/PG11 */ - {GPIOG_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D30/PG12 */ - {GPIOG_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D31/PG13 */ - {GPIOG_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D32/PG14 */ - {GPIOG_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D33/PG8 */ - {GPIOG_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D34/PG7 */ - {GPIOG_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D35/PG6 */ - {GPIOG_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D36/PB5 */ - {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D37/PB6 */ - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, /* D38/PB7 */ - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2}, + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2}, /* D39/PF6 */ - {GPIOF_BASE, 6, ADC4, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 6, 4, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D40/PF7 */ - {GPIOF_BASE, 7, ADC5, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 7, 5, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D41/PF8 */ - {GPIOF_BASE, 8, ADC6, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 8, 6, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D42/PF9 */ - {GPIOF_BASE, 9, ADC7, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 9, 7, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D43/PF10 */ - {GPIOF_BASE, 10, ADC8, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 10, 8, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D44/PF11 */ - {GPIOF_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D45/PB1 */ - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, + {GPIOB_BASE, 1, 9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, /* D46/PB0 */ - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, + {GPIOB_BASE, 0, 8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, /* D47/PA0 */ - {GPIOA_BASE, 0, ADC0, TIMER5_CH1_CCR, EXTI_CONFIG_PORTA, TIMER5, 1}, + {GPIOA_BASE, 0, 0, TIMER5_CH1_CCR, EXTI_CONFIG_PORTA, TIMER5, 1}, /* D48/PA1 */ - {GPIOA_BASE, 1, ADC1, TIMER5_CH2_CCR, EXTI_CONFIG_PORTA, TIMER5, 2}, /* FIXME (?) what to do about D48--D50 - also being TIMER2_CH[2,3,4]? */ + {GPIOA_BASE, 1, 1, TIMER5_CH2_CCR, EXTI_CONFIG_PORTA, TIMER5, 2}, /* FIXME (?) what to do about D48--D50 + also being TIMER2_CH[2,3,4]? */ /* D49/PA2 */ - {GPIOA_BASE, 2, ADC2, TIMER5_CH3_CCR, EXTI_CONFIG_PORTA, TIMER5, 3}, + {GPIOA_BASE, 2, 2, TIMER5_CH3_CCR, EXTI_CONFIG_PORTA, TIMER5, 3}, /* D50/PA3 */ - {GPIOA_BASE, 3, ADC3, TIMER5_CH4_CCR, EXTI_CONFIG_PORTA, TIMER5, 4}, + {GPIOA_BASE, 3, 3, TIMER5_CH4_CCR, EXTI_CONFIG_PORTA, TIMER5, 4}, /* D51/PA4 */ - {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + {GPIOA_BASE, 4, 4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, /* D52/PA5 */ - {GPIOA_BASE, 5, ADC5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + {GPIOA_BASE, 5, 5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, /* D53/PA6 */ - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, + {GPIOA_BASE, 6, 6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, /* D54/PA7 */ - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, + {GPIOA_BASE, 7, 7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, /* Right (triple) header */ /* D55/PF0 */ - {GPIOF_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D56/PD11 */ - {GPIOD_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D57/PD14 */ - {GPIOD_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D58/PF1 */ - {GPIOF_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D59/PD12 */ - {GPIOD_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D60/PD15 */ - {GPIOD_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D61/PF2 */ - {GPIOF_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D62/PD13 */ - {GPIOD_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D63/PD0 */ - {GPIOD_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D64/PF3 */ - {GPIOF_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D65/PE3 */ - {GPIOE_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D66/PD1 */ - {GPIOD_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D67/PF4 */ - {GPIOF_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D68/PE4 */ - {GPIOE_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D69/PE7 */ - {GPIOE_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 7, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D70/PF5 */ - {GPIOF_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D71/PE5 */ - {GPIOE_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D72/PE8 */ - {GPIOE_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D73/PF12 */ - {GPIOF_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D74/PE6 */ - {GPIOE_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 6, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D75/PE9 */ - {GPIOE_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D76/PF13 */ - {GPIOF_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D77/PE10 */ - {GPIOE_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D78/PF14 */ - {GPIOF_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D79/PG9 */ - {GPIOG_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D80/PE11 */ - {GPIOE_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D81/PF15 */ - {GPIOF_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, + {GPIOF_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, /* D82/PG10 */ - {GPIOG_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D83/PE12 */ - {GPIOE_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D84/PG0 */ - {GPIOG_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D85/PD5 */ - {GPIOD_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D86/PE13 */ - {GPIOE_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D87/PG1 */ - {GPIOG_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D88/PD4 */ - {GPIOD_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D89/PE14 */ - {GPIOE_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D90/PG2 */ - {GPIOG_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D91/PE1 */ - {GPIOE_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 1, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D92/PE15 */ - {GPIOE_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D93/PG3 */ - {GPIOG_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D94/PE0 */ - {GPIOE_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, + {GPIOE_BASE, 0, ADC_INVALID, 0, EXTI_CONFIG_PORTE, TIMER_INVALID, TIMER_INVALID}, /* D95/PD8 */ - {GPIOD_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 8, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D96/PG4 */ - {GPIOG_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D97/PD9 */ - {GPIOD_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, + {GPIOD_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D98/PG5 */ - {GPIOG_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, + {GPIOG_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTG, TIMER_INVALID, TIMER_INVALID}, /* D99/PD10 */ - {GPIOD_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID} + {GPIOD_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID} }; #define BOARD_INIT do { \ @@ -395,11 +396,13 @@ typedef struct PinMapping { #elif defined(BOARD_maple_mini) - #define CYCLES_PER_MICROSECOND 72 + #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_BUTTON_PIN 32 + #define BOARD_LED_PIN 33 + + #define NR_GPIO_PINS 34 static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { /* D0/PB11 */ @@ -409,23 +412,23 @@ typedef struct PinMapping { /* D2/PB2 */ {GPIOB_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D3/PB0 */ - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, + {GPIOB_BASE, 0, 8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, /* D4/PA7 */ - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, + {GPIOA_BASE, 7, 7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, /* D5/PA6 */ - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, + {GPIOA_BASE, 6, 6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, /* D6/PA5 */ - {GPIOA_BASE, 5, ADC5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + {GPIOA_BASE, 5, 5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, /* D7/PA4 */ - {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, + {GPIOA_BASE, 4, 4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, /* D8/PA3 */ - {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, + {GPIOA_BASE, 3, 3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, /* D9/PA2 */ - {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, + {GPIOA_BASE, 2, 2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, /* D10/PA1 */ - {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, + {GPIOA_BASE, 1, 1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, /* D11/PA0 */ - {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1}, + {GPIOA_BASE, 0, 0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1}, /* D12/PC15 */ {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D13/PC14 */ @@ -469,7 +472,7 @@ typedef struct PinMapping { /* D32/PB8 */ {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB, TIMER4, 3}, /* D33/PB1 */ - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, + {GPIOB_BASE, 1, 9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, }; /* since we want the Serial Wire/JTAG pins as GPIOs, disable both diff --git a/wirish/ext_interrupts.h b/wirish/ext_interrupts.h index 304e267..4e22c71 100644 --- a/wirish/ext_interrupts.h +++ b/wirish/ext_interrupts.h @@ -86,7 +86,7 @@ void detachInterrupt(uint8 pin); * * @see noInterrupts() */ -static ALWAYS_INLINE void interrupts() { +static inline void interrupts() { nvic_globalirq_enable(); } @@ -100,7 +100,7 @@ static ALWAYS_INLINE void interrupts() { * * @see interrupts() */ -static ALWAYS_INLINE void noInterrupts() { +static inline void noInterrupts() { nvic_globalirq_disable(); } diff --git a/wirish/wirish.c b/wirish/wirish.c index 622cdfd..4c84d26 100644 --- a/wirish/wirish.c +++ b/wirish/wirish.c @@ -47,14 +47,10 @@ void init(void) { flash_enable_prefetch(); flash_set_latency(FLASH_WAIT_STATE_2); -#if NR_FSMC > 0 +#ifdef STM32_HIGH_DENSITY fsmc_native_sram_init(); #endif -#if NR_DAC_PINS > 0 - dac_init(); -#endif - /* initialize clocks */ rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9); rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); @@ -67,16 +63,18 @@ void init(void) { /* Initialize the ADC for slow conversions, to allow for high impedance inputs. */ - adc_init(ADC_SMPR_55_5); -// timer_init(TIMER1, 1); -// timer_init(TIMER2, 1); -// timer_init(TIMER3, 1); -// timer_init(TIMER4, 1); -//#if NR_TIMERS >= 8 -// timer_init(TIMER5, 1); -// timer_init(TIMER8, 1); -//#endif -// setupUSB(); + adc_init(ADC1, 0); + adc_set_sample_rate(ADC1, ADC_SMPR_55_5); + + timer_init(TIMER1, 1); + timer_init(TIMER2, 1); + timer_init(TIMER3, 1); + timer_init(TIMER4, 1); +#ifdef STM32_HIGH_DENSITY + timer_init(TIMER5, 1); + timer_init(TIMER8, 1); +#endif + setupUSB(); /* include the board-specific init macro */ BOARD_INIT; diff --git a/wirish/wirish_analog.c b/wirish/wirish_analog.c index 3c63342..a658184 100644 --- a/wirish/wirish_analog.c +++ b/wirish/wirish_analog.c @@ -33,9 +33,9 @@ /* Assumes that the ADC has been initialized and that the pin is set * to ANALOG_INPUT */ uint32 analogRead(uint8 pin) { - if(PIN_MAP[pin].adc == ADC_INVALID) { + if(PIN_MAP[pin].adc_channel == ADC_INVALID) { return 0; } - return adc_read(PIN_MAP[pin].adc); + return adc_read(ADC1, PIN_MAP[pin].adc_channel); } |