diff options
-rw-r--r-- | Makefile | 37 | ||||
-rw-r--r-- | docs/source/language.rst | 57 | ||||
-rw-r--r-- | examples/test-bkp.cpp | 38 | ||||
-rw-r--r-- | examples/test-session.cpp | 3 | ||||
-rw-r--r-- | libmaple/adc.c | 2 | ||||
-rw-r--r-- | libmaple/adc.h | 4 | ||||
-rw-r--r-- | libmaple/bkp.c | 12 | ||||
-rw-r--r-- | libmaple/bkp.h | 8 | ||||
-rw-r--r-- | libmaple/libmaple.h | 163 | ||||
-rw-r--r-- | libmaple/libmaple_types.h | 2 | ||||
-rw-r--r-- | libmaple/timers.c | 10 | ||||
-rw-r--r-- | libmaple/timers.h | 6 | ||||
-rw-r--r-- | libmaple/usart.c | 12 | ||||
-rw-r--r-- | libmaple/usart.h | 2 | ||||
-rw-r--r-- | libmaple/usb/descriptors.c | 73 | ||||
-rw-r--r-- | libmaple/usb/usb_config.h | 76 | ||||
-rw-r--r-- | libmaple/util.c | 23 | ||||
-rw-r--r-- | libmaple/util.h | 33 | ||||
-rw-r--r-- | wirish/HardwareTimer.cpp | 4 | ||||
-rw-r--r-- | wirish/HardwareTimer.h | 2 | ||||
-rw-r--r-- | wirish/boards.h | 18 | ||||
-rw-r--r-- | wirish/ext_interrupts.h | 4 | ||||
-rw-r--r-- | wirish/wirish.c | 4 |
23 files changed, 308 insertions, 285 deletions
@@ -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/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 index 27f87bd..d0aa564 100644 --- a/examples/test-bkp.cpp +++ b/examples/test-bkp.cpp @@ -7,59 +7,61 @@ void print_bkp_contents(); void write_to_bkp(uint16 val); +#define comm Serial2 + void setup() { pinMode(BOARD_BUTTON_PIN, INPUT); - Serial2.begin(9600); - Serial2.println("*** Beginning BKP test"); + comm.begin(9600); + comm.println("*** Beginning BKP test"); - Serial2.println("Init..."); + comm.println("Init..."); bkp_init(); - Serial2.println("Done."); + comm.println("Done."); print_bkp_contents(); write_to_bkp(10); print_bkp_contents(); - Serial2.println("Enabling backup writes."); + comm.println("Enabling backup writes."); bkp_enable_writes(); write_to_bkp(20); print_bkp_contents(); - Serial2.println("Disabling backup writes."); + comm.println("Disabling backup writes."); bkp_disable_writes(); write_to_bkp(30); print_bkp_contents(); - Serial2.println("Done testing backup registers; press button to enable " + 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); - Serial2.println(); + comm.println(); } void loop() { } void print_bkp_contents() { - Serial2.println("Backup data register contents:"); + comm.println("Backup data register contents:"); char buf[100]; - for (int i = 1; i <= NR_BKP_REGS; i++) { + for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { snprintf(buf, sizeof buf, "DR%d: %d ", i, bkp_read(i)); - Serial2.print(buf); - if (i % 5 == 0) Serial2.println(); + comm.print(buf); + if (i % 5 == 0) comm.println(); } - Serial2.println(); + comm.println(); } void write_to_bkp(uint16 val) { - Serial2.print("Attempting to write "); - Serial2.print(val); - Serial2.println(" to backup registers..."); - for (int i = 1; i <= NR_BKP_REGS; i++) { + 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); } - Serial2.println("Done."); + comm.println("Done."); } __attribute__((constructor)) void premain() { diff --git a/examples/test-session.cpp b/examples/test-session.cpp index 86bab6d..72d64d6 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -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 17d63b8..cd71118 100644 --- a/libmaple/adc.c +++ b/libmaple/adc.c @@ -49,7 +49,7 @@ adc_dev adc2 = { }; const adc_dev *ADC2 = &adc2; -#if NR_ADCS >= 3 +#ifdef STM32_HIGH_DENSITY adc_dev adc3 = { .regs = ADC3_BASE, .clk_id = RCC_ADC3 diff --git a/libmaple/adc.h b/libmaple/adc.h index ab6e643..ac386fb 100644 --- a/libmaple/adc.h +++ b/libmaple/adc.h @@ -68,7 +68,7 @@ typedef struct adc_dev { extern const adc_dev *ADC1; extern const adc_dev *ADC2; -#if NR_ADCS >= 3 +#ifdef STM32_HIGH_DENSITY extern const adc_dev *ADC3; #endif @@ -190,7 +190,7 @@ static inline void adc_disable(const adc_dev *dev) { static inline void adc_disable_all(void) { adc_disable(ADC1); adc_disable(ADC2); -#if NR_ADCS >= 3 +#ifdef STM32_HIGH_DENSITY adc_disable(ADC3); #endif } diff --git a/libmaple/bkp.c b/libmaple/bkp.c index ac9aeae..ed107d8 100644 --- a/libmaple/bkp.c +++ b/libmaple/bkp.c @@ -69,7 +69,8 @@ void bkp_disable_writes(void) { /** * Read a value from given backup data register. - * @param reg Data register to read, from 1 to NR_BKP_REGS (10 on Maple). + * @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) { __io uint32* dr = data_register(reg); @@ -85,7 +86,8 @@ uint16 bkp_read(uint8 reg) { * * Write access to backup registers must be enabled. * - * @param reg Data register to write, from 1 to NR_BKP_REGS (10 on Maple). + * @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() */ @@ -101,16 +103,16 @@ void bkp_write(uint8 reg, uint16 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)--NR_BKP_REGS, beginning at BKP_BASE->DR10. + * (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 > NR_BKP_REGS) { + if (reg < 1 || reg > BKP_NR_DATA_REGS) { return 0; } -#if NR_BKP_REGS == NR_LOW_DRS +#if BKP_NR_DATA_REGS == NR_LOW_DRS return (uint32*)BKP_BASE + reg; #else if (reg <= NR_LOW_DRS) { diff --git a/libmaple/bkp.h b/libmaple/bkp.h index ce8e6c7..96ef8d2 100644 --- a/libmaple/bkp.h +++ b/libmaple/bkp.h @@ -38,6 +38,12 @@ extern "C" { #endif +#if defined(STM32_MEDIUM_DENSITY) +#define BKP_NR_DATA_REGS 10 +#elif defined(STM32_HIGH_DENSITY) +#define BKP_NR_DATA_REGS 42 +#endif + typedef struct bkp_reg_map { const uint32 RESERVED1; __io uint32 DR1; ///< Data register 1 @@ -53,7 +59,7 @@ typedef struct bkp_reg_map { __io uint32 RTCCR; ///< RTC control register __io uint32 CR; ///< Control register __io uint32 CSR; ///< Control and status register -#if NR_BKP_REGS > 10 +#ifdef STM32_HIGH_DENSITY const uint32 RESERVED2; const uint32 RESERVED3; __io uint32 DR11; ///< Data register 11 diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h index 4f9a71a..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 "util.h" -/* General configuration */ -#define DEBUG_NONE 0 -#define DEBUG_FAULT 1 -#define DEBUG_ALL 2 - -#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 - - /* Number of ADCs */ - #define NR_ADCS 2 - - /* Has an FSMC bus? */ - #define NR_FSMC 0 - - /* Has a DAC? */ - #define NR_DAC_PINS 0 - - /* 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_ADCS 3 - #define NR_FSMC 1 - #define NR_DAC_PINS 2 - - #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_ADCS 2 - #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/timers.c b/libmaple/timers.c index 29aeeba..ff548c0 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, 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..030d3cc 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, @@ -107,7 +107,7 @@ void USART3_IRQHandler(void) { usart_irq(USART3); } -#if NR_USART >= 5 +#ifdef STM32_HIGH_DENSITY void UART4_IRQHandler(void) { usart_irq(UART4); } @@ -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_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 11f9b34..481cd60 100644 --- a/libmaple/util.c +++ b/libmaple/util.c @@ -34,6 +34,21 @@ #include "adc.h" #include "timers.h" +/* 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 + /* Error assert + fade */ void _fail(const char* file, int line, const char* exp) { int32 slope = 1; @@ -67,8 +82,10 @@ void _fail(const char* file, int line, const char* exp) { usart_putc(ERROR_USART_NUM, '\n'); usart_putc(ERROR_USART_NUM, '\r'); +#ifdef HAVE_ERROR_LED /* Turn on the error LED */ gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); +#endif /* Turn the USB interrupt back on so the bootloader keeps on functioning */ nvic_irq_enable(NVIC_INT_USBHP); @@ -79,6 +96,7 @@ void _fail(const char* file, int line, const char* exp) { } void throb(void) { +#ifdef HAVE_ERROR_LED int32 slope = 1; uint32 CC = 0x0000; uint32 TOP_CNT = 0x0200; @@ -105,5 +123,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 63427cc..28ce970 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,9 +52,14 @@ #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 */ +/* Convert peripheral address */ #define BITBAND_PERI(a, b) ((BITBAND_PERI_BASE + \ ((uint32)a - BITBAND_PERI_REF) * 32 + (b * 4))) @@ -63,18 +79,9 @@ #define __write(reg, value) (*(volatile uint32*)(reg) = (value)) #define IS_POWER_OF_TWO(v) (v && !(v & (v - 1))) - -#ifdef __cplusplus -extern "C"{ -#endif - 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 */ @@ -100,5 +107,9 @@ void throb(void); #define ASSERT_FAULT(exp) (void)((0)) #endif +#ifdef __cplusplus +} // extern "C" +#endif + #endif 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 ac3a74d..989eea1 100644 --- a/wirish/boards.h +++ b/wirish/boards.h @@ -70,8 +70,12 @@ 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 */ @@ -173,6 +177,8 @@ 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 */ @@ -390,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 */ 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 c5dec22..4c84d26 100644 --- a/wirish/wirish.c +++ b/wirish/wirish.c @@ -47,7 +47,7 @@ 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 @@ -70,7 +70,7 @@ void init(void) { timer_init(TIMER2, 1); timer_init(TIMER3, 1); timer_init(TIMER4, 1); -#if NR_TIMERS >= 8 +#ifdef STM32_HIGH_DENSITY timer_init(TIMER5, 1); timer_init(TIMER8, 1); #endif |