aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--Makefile37
-rw-r--r--build-targets.mk2
-rw-r--r--docs/source/language.rst57
-rw-r--r--examples/test-bkp.cpp80
-rw-r--r--examples/test-dac.cpp6
-rw-r--r--examples/test-session.cpp5
-rw-r--r--libmaple/adc.c142
-rw-r--r--libmaple/adc.h203
-rw-r--r--libmaple/bkp.c112
-rw-r--r--libmaple/bkp.h102
-rw-r--r--libmaple/dac.c89
-rw-r--r--libmaple/dac.h135
-rw-r--r--libmaple/dma.c14
-rw-r--r--libmaple/exc.S71
-rw-r--r--libmaple/exti.c14
-rw-r--r--libmaple/libmaple.h163
-rw-r--r--libmaple/libmaple_types.h2
-rw-r--r--libmaple/pwr.c42
-rw-r--r--libmaple/pwr.h64
-rw-r--r--libmaple/rcc.c21
-rw-r--r--libmaple/rcc.h15
-rw-r--r--libmaple/systick.c2
-rw-r--r--libmaple/timers.c18
-rw-r--r--libmaple/timers.h6
-rw-r--r--libmaple/usart.c22
-rw-r--r--libmaple/usart.h2
-rw-r--r--libmaple/usb/descriptors.c73
-rw-r--r--libmaple/usb/usb.c2
-rw-r--r--libmaple/usb/usb.h2
-rw-r--r--libmaple/usb/usb_config.h76
-rw-r--r--libmaple/util.c69
-rw-r--r--libmaple/util.h37
-rw-r--r--support/ld/common_ram.inc221
-rw-r--r--support/ld/common_rom.inc223
-rw-r--r--support/ld/libcs3-lanchon-stm32.abin10134 -> 0 bytes
-rw-r--r--support/ld/libcs3-lanchon-stm32.tar.gzbin2775 -> 0 bytes
-rw-r--r--support/ld/libcs3_stm32_high_density.abin0 -> 9464 bytes
-rw-r--r--support/ld/libcs3_stm32_med_density.abin0 -> 9464 bytes
-rw-r--r--support/ld/libcs3_stm32_src/Makefile35
-rw-r--r--support/ld/libcs3_stm32_src/start.S27
-rw-r--r--support/ld/libcs3_stm32_src/start_c.c58
-rw-r--r--support/ld/libcs3_stm32_src/stm32_isrs.S235
-rw-r--r--support/ld/libcs3_stm32_src/stm32_vector_table.S90
-rw-r--r--support/ld/maple/flash.ld219
-rw-r--r--support/ld/maple/jtag.ld192
-rw-r--r--support/ld/maple/ram.ld227
-rw-r--r--support/ld/maple_mini/flash.ld218
-rw-r--r--support/ld/maple_mini/jtag.ld192
-rw-r--r--support/ld/maple_mini/ram.ld227
-rw-r--r--support/ld/maple_native/flash.ld211
-rw-r--r--support/ld/maple_native/jtag.ld187
-rw-r--r--support/ld/maple_native/ram.ld220
-rw-r--r--support/ld/names.inc137
-rw-r--r--support/ld/src.zipbin15774 -> 0 bytes
-rw-r--r--wirish/HardwareTimer.cpp4
-rw-r--r--wirish/HardwareTimer.h2
-rw-r--r--wirish/boards.h325
-rw-r--r--wirish/ext_interrupts.h4
-rw-r--r--wirish/wirish.c28
-rw-r--r--wirish/wirish_analog.c4
61 files changed, 2377 insertions, 2600 deletions
diff --git a/.gitignore b/.gitignore
index be8bc38..eab8f74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,11 @@
build/
docs/build/
+main.cpp
libmaple.layout
tags
TAGS
*~
*.swp
docs/doxygen/
-<<<<<<< Updated upstream
arm
-=======
-notes/
->>>>>>> Stashed changes
+cscope*
diff --git a/Makefile b/Makefile
index 2782c0a..149f54a 100644
--- a/Makefile
+++ b/Makefile
@@ -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
deleted file mode 100644
index 4ed858f..0000000
--- a/support/ld/libcs3-lanchon-stm32.a
+++ /dev/null
Binary files differ
diff --git a/support/ld/libcs3-lanchon-stm32.tar.gz b/support/ld/libcs3-lanchon-stm32.tar.gz
deleted file mode 100644
index 5cbcf7d..0000000
--- a/support/ld/libcs3-lanchon-stm32.tar.gz
+++ /dev/null
Binary files differ
diff --git a/support/ld/libcs3_stm32_high_density.a b/support/ld/libcs3_stm32_high_density.a
new file mode 100644
index 0000000..472ed28
--- /dev/null
+++ b/support/ld/libcs3_stm32_high_density.a
Binary files differ
diff --git a/support/ld/libcs3_stm32_med_density.a b/support/ld/libcs3_stm32_med_density.a
new file mode 100644
index 0000000..07a991d
--- /dev/null
+++ b/support/ld/libcs3_stm32_med_density.a
Binary files differ
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
deleted file mode 100644
index 58ff908..0000000
--- a/support/ld/src.zip
+++ /dev/null
Binary files differ
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);
}