From 4e90248a2e81ec7bd8d3cfa858cef4a045cc1003 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Sun, 27 Feb 2011 11:42:56 -0500 Subject: Cleaned out libmaple.h; this had wide-ranging implications. Many of the #defines in libmaple.h were board-specific, not MCU-specific. Most of these were only used by code under libmaple/usb/. These were moved into usb_config.h, and are clearly marked as being terrible hacks. I'm going to treat the USB stack as a black box that we'll deal with later. Further, instead of having a variety of #defines like "How many USARTS do I have?", we decide that based on the density of the chip. This is determined by testing for STM32_MEDIUM_DENSITY or STM32_HIGH_DENSITY defines. libmaple currently doesn't support low-density chips, so that suffices. The Makefile will set these automatically based on the MCU. Other offending #defines are ERROR_LED_PORT and ERROR_LED_PIN; these were made optional, but they're set in the Makefile as a hack to keep things working. --- libmaple/usb/descriptors.c | 73 ++++++++++++++++++++++++-------------------- libmaple/usb/usb_config.h | 76 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 40 deletions(-) (limited to 'libmaple/usb') 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 -- cgit v1.2.3 From 214941537f2211d5e2ef16e34440485d7e872d1a Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Sun, 27 Feb 2011 15:49:51 -0500 Subject: Refactor linker scripts. Rename irq and exception handlers. Add common linker scripts for ram and rom. Add medium and high density libraries for libcs3. --- libmaple/dma.c | 14 +- libmaple/exc.S | 44 ++++- libmaple/exti.c | 14 +- libmaple/systick.c | 2 +- libmaple/timers.c | 8 +- libmaple/usart.c | 10 +- libmaple/usb/usb.c | 2 +- libmaple/usb/usb.h | 2 +- support/ld/common_ram.inc | 221 +++++++++++++++++++++ support/ld/common_rom.inc | 223 +++++++++++++++++++++ support/ld/libcs3-lanchon-stm32.a | Bin 10134 -> 0 bytes support/ld/libcs3-lanchon-stm32.tar.gz | Bin 2775 -> 0 bytes support/ld/libcs3_stm32_high_density.a | Bin 0 -> 9464 bytes support/ld/libcs3_stm32_med_density.a | Bin 0 -> 9464 bytes support/ld/libcs3_stm32_src/Makefile | 35 ++++ support/ld/libcs3_stm32_src/start.S | 27 +++ support/ld/libcs3_stm32_src/start_c.c | 58 ++++++ support/ld/libcs3_stm32_src/stm32_isrs.S | 235 +++++++++++++++++++++++ support/ld/libcs3_stm32_src/stm32_vector_table.S | 90 +++++++++ support/ld/maple/flash.ld | 219 ++------------------- support/ld/maple/jtag.ld | 192 ++---------------- support/ld/maple/ram.ld | 227 ++-------------------- support/ld/maple_mini/flash.ld | 218 ++------------------- support/ld/maple_mini/jtag.ld | 192 ++---------------- support/ld/maple_mini/ram.ld | 227 ++-------------------- support/ld/maple_native/flash.ld | 211 ++------------------ support/ld/maple_native/jtag.ld | 187 ++---------------- support/ld/maple_native/ram.ld | 220 ++------------------- support/ld/names.inc | 137 +++++++------ support/ld/src.zip | Bin 15774 -> 0 bytes 30 files changed, 1163 insertions(+), 1852 deletions(-) create mode 100644 support/ld/common_ram.inc create mode 100644 support/ld/common_rom.inc delete mode 100644 support/ld/libcs3-lanchon-stm32.a delete mode 100644 support/ld/libcs3-lanchon-stm32.tar.gz create mode 100644 support/ld/libcs3_stm32_high_density.a create mode 100644 support/ld/libcs3_stm32_med_density.a create mode 100644 support/ld/libcs3_stm32_src/Makefile create mode 100644 support/ld/libcs3_stm32_src/start.S create mode 100644 support/ld/libcs3_stm32_src/start_c.c create mode 100644 support/ld/libcs3_stm32_src/stm32_isrs.S create mode 100644 support/ld/libcs3_stm32_src/stm32_vector_table.S delete mode 100644 support/ld/src.zip (limited to 'libmaple/usb') 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 a9f6561..d01e3d5 100644 --- a/libmaple/exc.S +++ b/libmaple/exc.S @@ -41,16 +41,42 @@ # SP--> r0 .text -.globl HardFaultException +.globl __exc_hardfault +.globl __exc_nmi +.globl __exc_hardfault +.globl __exc_memmanage +.globl __exc_busfault +.globl __exc_usagefault + +/* TODO: Fix this up. */ +.thumb_func +__exc_nmi: + mov r0, #1 + +.thumb_func +__exc_hardfault: + mov r0, #2 + .thumb_func -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 +__exc_memmanage: + mov r0, #3 + +.thumb_func +__exc_busfault: + mov r0, #4 + +.thumb_func +__exc_usagefault: + mov r0, #5 + +__default: + 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 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/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 ff548c0..c561d39 100644 --- a/libmaple/timers.c +++ b/libmaple/timers.c @@ -382,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; @@ -418,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; @@ -453,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; @@ -489,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/usart.c b/libmaple/usart.c index 030d3cc..494a29f 100644 --- a/libmaple/usart.c +++ b/libmaple/usart.c @@ -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); } #ifdef STM32_HIGH_DENSITY -void UART4_IRQHandler(void) { +void __irq_uart4(void) { usart_irq(UART4); } -void UART5_IRQHandler(void) { +void __irq_uart5(void) { usart_irq(UART5); } #endif 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/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 Binary files a/support/ld/libcs3-lanchon-stm32.a and /dev/null 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 Binary files a/support/ld/libcs3-lanchon-stm32.tar.gz and /dev/null 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 Binary files /dev/null and b/support/ld/libcs3_stm32_high_density.a 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 Binary files /dev/null and b/support/ld/libcs3_stm32_med_density.a 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 a0e1fb2..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_IRQHandler) -EXTERN (I2C1_ER_IRQHandler) -EXTERN (I2C2_EV_IRQHandler) -EXTERN (I2C2_ER_IRQHandler) -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 Binary files a/support/ld/src.zip and /dev/null differ -- cgit v1.2.3 From c8da1c3b7b6eb450138a00af9bbbee607f596837 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Mon, 7 Mar 2011 13:11:54 -0500 Subject: [WIP] GPIO refactor: seems ok, ready for review --- Makefile | 8 +- docs/Doxyfile | 6 +- examples/test-session.cpp | 28 +-- libmaple/adc.c | 4 +- libmaple/adc.h | 38 ++-- libmaple/bitband.h | 83 +++++++++ libmaple/bkp.c | 6 +- libmaple/bkp.h | 16 +- libmaple/dac.c | 6 +- libmaple/dac.h | 10 +- libmaple/exti.c | 244 +++++++++++++++---------- libmaple/exti.h | 158 ++++------------ libmaple/fsmc.c | 89 ++++----- libmaple/fsmc.h | 5 +- libmaple/gpio.c | 165 ++++++++++++++--- libmaple/gpio.h | 391 ++++++++++++++++++++++++++++++---------- libmaple/libmaple.h | 2 +- libmaple/libmaple_types.h | 1 + libmaple/pwr.h | 9 +- libmaple/rcc.h | 3 +- libmaple/ring_buffer.h | 17 +- libmaple/spi.c | 18 +- libmaple/usb/usb.c | 33 +++- libmaple/usb/usb_callbacks.c | 2 +- libmaple/usb/usb_config.h | 7 +- libmaple/usb/usb_hardware.c | 41 ----- libmaple/usb/usb_hardware.h | 36 +--- libmaple/util.c | 6 +- libmaple/util.h | 35 ++-- notes/coding_standard.txt | 85 +++++---- notes/exti.txt | 67 +++++++ wirish/HardwareTimer.cpp | 11 +- wirish/boards.cpp | 387 +++++++++++++++++++++++++++++++++++++++ wirish/boards.h | 401 ++--------------------------------------- wirish/comm/HardwareSerial.cpp | 14 +- wirish/comm/HardwareSerial.h | 4 +- wirish/ext_interrupts.c | 79 -------- wirish/ext_interrupts.cpp | 82 +++++++++ wirish/ext_interrupts.h | 11 +- wirish/io.h | 11 +- wirish/pwm.c | 48 ----- wirish/pwm.cpp | 48 +++++ wirish/pwm.h | 13 +- wirish/rules.mk | 32 ++-- wirish/time.c | 52 ------ wirish/time.cpp | 52 ++++++ wirish/time.h | 9 - wirish/wirish.c | 81 --------- wirish/wirish.cpp | 82 +++++++++ wirish/wirish.h | 16 +- wirish/wirish_analog.c | 41 ----- wirish/wirish_analog.cpp | 41 +++++ wirish/wirish_digital.c | 142 --------------- wirish/wirish_digital.cpp | 143 +++++++++++++++ wirish/wirish_math.h | 9 +- wirish/wirish_shift.c | 40 ---- wirish/wirish_shift.cpp | 40 ++++ 57 files changed, 1928 insertions(+), 1580 deletions(-) create mode 100644 libmaple/bitband.h create mode 100644 notes/exti.txt create mode 100644 wirish/boards.cpp delete mode 100644 wirish/ext_interrupts.c create mode 100644 wirish/ext_interrupts.cpp delete mode 100644 wirish/pwm.c create mode 100644 wirish/pwm.cpp delete mode 100644 wirish/time.c create mode 100644 wirish/time.cpp delete mode 100644 wirish/wirish.c create mode 100644 wirish/wirish.cpp delete mode 100644 wirish/wirish_analog.c create mode 100644 wirish/wirish_analog.cpp delete mode 100644 wirish/wirish_digital.c create mode 100644 wirish/wirish_digital.cpp delete mode 100644 wirish/wirish_shift.c create mode 100644 wirish/wirish_shift.cpp (limited to 'libmaple/usb') diff --git a/Makefile b/Makefile index 01e1e72..3804421 100644 --- a/Makefile +++ b/Makefile @@ -13,21 +13,21 @@ PRODUCT_ID := 0003 ifeq ($(BOARD), maple) MCU := STM32F103RB PRODUCT_ID := 0003 - ERROR_LED_PORT := GPIOA_BASE + ERROR_LED_PORT := GPIOA 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_PORT := GPIOC 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_PORT := GPIOB ERROR_LED_PIN := 1 DENSITY := STM32_MEDIUM_DENSITY endif @@ -45,7 +45,7 @@ SUPPORT_PATH := $(SRCROOT)/support # Compilation flags. # FIXME remove the ERROR_LED config GLOBAL_CFLAGS := -Os -g3 -gdwarf-2 -mcpu=cortex-m3 -mthumb -march=armv7-m \ - -nostdlib \ + -nostdlib \ -ffunction-sections -fdata-sections -Wl,--gc-sections \ -DBOARD_$(BOARD) -DMCU_$(MCU) \ -DERROR_LED_PORT=$(ERROR_LED_PORT) \ diff --git a/docs/Doxyfile b/docs/Doxyfile index 3290843..9bf02fc 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -620,7 +620,9 @@ RECURSIVE = YES # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +# FIXME The USB thing needs to get redone (ST code stripped out, +# etc.). Until then, just ignore it. +EXCLUDE = ../libmaple/usb/ # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded @@ -1369,7 +1371,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = ALWAYS_INLINE= \ +PREDEFINED = __attribute__()= \ __cplusplus # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then diff --git a/examples/test-session.cpp b/examples/test-session.cpp index 72d64d6..ea631ca 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -351,22 +351,22 @@ void cmd_everything(void) { // TODO } void fast_gpio(int maple_pin) { - GPIO_Port *port = PIN_MAP[maple_pin].port; + gpio_dev *dev = PIN_MAP[maple_pin].gpio_device; uint32 pin = PIN_MAP[maple_pin].pin; - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); - gpio_write_bit(port, pin, 1); gpio_write_bit(port, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); + gpio_write_bit(dev, pin, 1); gpio_write_bit(dev, pin, 0); } void cmd_serial1_serial3(void) { diff --git a/libmaple/adc.c b/libmaple/adc.c index a464746..9626a40 100644 --- a/libmaple/adc.c +++ b/libmaple/adc.c @@ -126,8 +126,8 @@ void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate) { * @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); + __io uint32 *rstcal_bit = bb_peripv(&(dev->regs->CR2), 3); + __io uint32 *cal_bit = bb_peripv(&(dev->regs->CR2), 2); *rstcal_bit = 1; while (*rstcal_bit) diff --git a/libmaple/adc.h b/libmaple/adc.h index ac386fb..4811dbc 100644 --- a/libmaple/adc.h +++ b/libmaple/adc.h @@ -30,14 +30,16 @@ #ifndef _ADC_H_ #define _ADC_H_ -#include "util.h" +#include "libmaple.h" +#include "bitband.h" #include "rcc.h" #ifdef __cplusplus extern "C"{ #endif +/** ADC register map type. */ typedef struct adc_reg_map { __io uint32 SR; ///< Status register __io uint32 CR1; ///< Control register 1 @@ -61,22 +63,30 @@ typedef struct adc_reg_map { __io uint32 DR; ///< Regular data register } adc_reg_map; +/** ADC device type. */ typedef struct adc_dev { - adc_reg_map *regs; - rcc_clk_id clk_id; + adc_reg_map *regs; /**< Register map */ + rcc_clk_id clk_id; /**< RCC clock information */ } adc_dev; +/** ADC1 device. */ extern const adc_dev *ADC1; +/** ADC2 device. */ extern const adc_dev *ADC2; #ifdef STM32_HIGH_DENSITY +/** ADC3 device. */ extern const adc_dev *ADC3; #endif /* * ADC peripheral base addresses */ + +/** ADC1 register map base pointer. */ #define ADC1_BASE ((adc_reg_map*)0x40012400) +/** ADC2 register map base pointer. */ #define ADC2_BASE ((adc_reg_map*)0x40012800) +/** ADC3 register map base pointer. */ #define ADC3_BASE ((adc_reg_map*)0x40013C00) /* @@ -138,8 +148,8 @@ void adc_set_sample_rate(const adc_dev *dev, adc_smp_rate smp_rate); /** * @brief Perform a single synchronous software triggered conversion on a - * channel - * @param regs ADC register map + * channel. + * @param dev ADC device to use for reading. * @param channel channel to convert * @return conversion result */ @@ -161,27 +171,27 @@ static inline uint32 adc_read(const adc_dev *dev, uint8 channel) { /** * @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 + * @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); + *bb_peripv(&dev->regs->CR2, 20) = !!enable; } /** * @brief Enable an adc peripheral - * @param regs register map of peripheral to enable + * @param dev ADC device to enable */ static inline void adc_enable(const adc_dev *dev) { - __write(BITBAND_PERI(&(dev->regs->CR2), 0), 1); + *bb_peripv(&dev->regs->CR2, 0) = 1; } /** - * @brief Disable an adc peripheral - * @param regs register map of peripheral to disable + * @brief Disable an ADC peripheral + * @param dev ADC device to disable */ static inline void adc_disable(const adc_dev *dev) { - __write(BITBAND_PERI(&(dev->regs->CR2), 0), 0); + *bb_peripv(&dev->regs->CR2, 0) = 0; } /** @@ -198,5 +208,5 @@ static inline void adc_disable_all(void) { #ifdef __cplusplus } // extern "C" #endif -#endif +#endif diff --git a/libmaple/bitband.h b/libmaple/bitband.h new file mode 100644 index 0000000..076335f --- /dev/null +++ b/libmaple/bitband.h @@ -0,0 +1,83 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2011 LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +/** + * @file bitband.h + * + * @brief Bit-banding utility functions + */ + +#define BB_SRAM_REF 0x20000000 +#define BB_SRAM_BASE 0x22000000 +#define BB_PERI_REF 0x40000000 +#define BB_PERI_BASE 0x42000000 + +static inline uint32* __bb_addr(void*, uint32, uint32, uint32); +static inline __io uint32* __bb_addrv(__io void*, uint32, uint32, uint32); + +/** + * @brief Obtain a pointer to the bit-band address corresponding to a + * bit in an SRAM address. + * @param address Address in the bit-banded SRAM region + * @param bit Bit in address to bit-band + */ +static inline uint32* bb_sramp(void *address, uint32 bit) { + return __bb_addr(address, bit, BB_SRAM_BASE, BB_SRAM_REF); +} + +/** + * @brief Obtain a pointer to the bit-band address corresponding to a + * bit in a volatile SRAM address. + * @param address Address in the bit-banded SRAM region + * @param bit Bit in address to bit-band + */ +static inline __io uint32* bb_srampv(__io void *address, uint32 bit) { + return __bb_addrv(address, bit, BB_SRAM_BASE, BB_SRAM_REF); +} + +/** + * @brief Obtain a pointer to the bit-band address corresponding to a + * bit in a peripheral address. + * @param address Address in the bit-banded peripheral region + * @param bit Bit in address to bit-band + */ +static inline __io uint32* bb_peripv(__io void *address, uint32 bit) { + return __bb_addrv(address, bit, BB_PERI_BASE, BB_PERI_REF); +} + +static inline uint32* __bb_addr(void *address, + uint32 bit, + uint32 bb_base, + uint32 bb_ref) { + return (uint32*)(bb_base + ((uint32)address - bb_ref) * 32 + bit * 4); +} + +static inline __io uint32* __bb_addrv(__io void *address, + uint32 bit, + uint32 bb_base, + uint32 bb_ref) { + return (__io uint32*)__bb_addr((void*)address, bit, bb_base, bb_ref); +} diff --git a/libmaple/bkp.c b/libmaple/bkp.c index ed107d8..b152069 100644 --- a/libmaple/bkp.c +++ b/libmaple/bkp.c @@ -27,7 +27,7 @@ #include "bkp.h" #include "pwr.h" #include "rcc.h" -#include "util.h" +#include "bitband.h" static inline __io uint32* data_register(uint8 reg); @@ -57,14 +57,14 @@ void bkp_init(void) { * @see bkp_init() */ void bkp_enable_writes(void) { - __write(BITBAND_PERI(&(PWR_BASE->CR), PWR_CR_DBP), 1); + *bb_peripv(&PWR_BASE->CR, PWR_CR_DBP) = 1; } /** * Disable write access to the backup registers. */ void bkp_disable_writes(void) { - __write(BITBAND_PERI(&(PWR_BASE->CR), PWR_CR_DBP), 0); + *bb_peripv(&PWR_BASE->CR, PWR_CR_DBP) = 0; } /** diff --git a/libmaple/bkp.h b/libmaple/bkp.h index 96ef8d2..cea39b6 100644 --- a/libmaple/bkp.h +++ b/libmaple/bkp.h @@ -44,6 +44,7 @@ extern "C" { #define BKP_NR_DATA_REGS 42 #endif +/** Backup peripheral register map type. */ typedef struct bkp_reg_map { const uint32 RESERVED1; __io uint32 DR1; ///< Data register 1 @@ -97,20 +98,17 @@ typedef struct bkp_reg_map { #endif } bkp_reg_map; +/** Backup peripheral register map base pointer. */ +#define BKP_BASE ((bkp_reg_map*)0x40006C00) + +/** Backup peripheral device type. */ typedef struct bkp_dev { - bkp_reg_map *regs; + bkp_reg_map *regs; /**< Register map */ } bkp_dev; -/** - * Backup device. - */ +/** Backup device. */ extern const bkp_dev *BKP; -/* - * Backup peripheral base. - */ -#define BKP_BASE ((bkp_reg_map*)0x40006C00) - void bkp_init(void); void bkp_enable_writes(void); void bkp_disable_writes(void); diff --git a/libmaple/dac.c b/libmaple/dac.c index 54b555b..ef3a9f9 100644 --- a/libmaple/dac.c +++ b/libmaple/dac.c @@ -80,15 +80,15 @@ void dac_write_channel(uint8 channel, uint16 val) { 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. + * all STM32 chips with a DAC. See RM0008 12.2. */ switch (channel) { case 1: - gpio_set_mode(GPIOA_BASE, 4, GPIO_MODE_INPUT_ANALOG); + gpio_set_mode(GPIOA, 4, GPIO_INPUT_ANALOG); DAC->regs->CR |= DAC_CR_EN1; break; case 2: - gpio_set_mode(GPIOA_BASE, 5, GPIO_MODE_INPUT_ANALOG); + gpio_set_mode(GPIOA, 5, GPIO_INPUT_ANALOG); DAC->regs->CR |= DAC_CR_EN2; break; } diff --git a/libmaple/dac.h b/libmaple/dac.h index bc64324..c897bb2 100644 --- a/libmaple/dac.h +++ b/libmaple/dac.h @@ -25,9 +25,10 @@ /** * @file dac.h * @brief Digital to analog converter header file - * See notes/dac.txt for more info */ +/* See notes/dac.txt for more info */ + #ifndef _DAC_H_ #define _DAC_H_ @@ -63,16 +64,15 @@ typedef struct dac_reg_map { __io uint32 DOR2; /**< Channel 2 data output register */ } dac_reg_map; +/** DAC device type. */ typedef struct dac_dev { - dac_reg_map *regs; + dac_reg_map *regs; /**< Register map */ } dac_dev; /** DAC device. */ extern const dac_dev *DAC; -/* - * DAC peripheral base address - */ +/** DAC register map base address */ #define DAC_BASE ((dac_reg_map*)0x40007400) /* diff --git a/libmaple/exti.c b/libmaple/exti.c index e8ad52a..8177e1e 100644 --- a/libmaple/exti.c +++ b/libmaple/exti.c @@ -23,19 +23,29 @@ *****************************************************************************/ /** + * @file exti.c * @brief External interrupt control routines */ #include "libmaple.h" #include "exti.h" #include "nvic.h" +#include "bitband.h" -typedef struct ExtIChannel { +/* + * Internal state + */ + +/* Status bitmaps, for external interrupts with multiplexed IRQs */ +static uint16 exti_9_5_en = 0; +static uint16 exti_15_10_en = 0; + +typedef struct exti_channel { void (*handler)(void); uint32 irq_line; -} ExtIChannel; +} exti_channel; -static ExtIChannel exti_channels[] = { +static exti_channel exti_channels[] = { { .handler = NULL, .irq_line = NVIC_EXTI0 }, // EXTI0 { .handler = NULL, .irq_line = NVIC_EXTI1 }, // EXTI1 { .handler = NULL, .irq_line = NVIC_EXTI2 }, // EXTI2 @@ -54,63 +64,127 @@ static ExtIChannel exti_channels[] = { { .handler = NULL, .irq_line = NVIC_EXTI15_10 }, // EXTI15 }; -static inline void clear_pending(int bit) { - __set_bits(EXTI_PR, BIT(bit)); - /* If the pending bit is cleared as the last instruction in an ISR, - * it won't actually be cleared in time and the ISR will fire again. - * Insert a 2-cycle buffer to allow it to take effect. */ - asm volatile("nop"); - asm volatile("nop"); -} +/* + * Convenience routines + */ + +static inline void enable_irq(afio_exti_num exti_num); +static inline void maybe_disable_irq(afio_exti_num exti_num); + +/** + * @brief Register a handler to run upon external interrupt. + * + * This function assumes that the interrupt request corresponding to + * the given external interrupt is masked. + * + * @param num External interrupt line number. + * @param port Port to use as source input for external interrupt. + * @param handler Function handler to execute when interrupt is triggered. + * @param mode Type of transition to trigger on, one of: + * EXTI_RISING, EXTI_FALLING, EXTI_RISING_FALLING. + * @see exti_num + * @see exti_port + * @see exti_trigger_mode + */ +void exti_attach_interrupt(afio_exti_num num, + afio_exti_port port, + voidFuncPtr handler, + exti_trigger_mode mode) { + ASSERT(handler); -static inline void dispatch_handler(uint32 channel) { - ASSERT(exti_channels[channel].handler); - if (exti_channels[channel].handler) { - (exti_channels[channel].handler)(); + /* Register the handler */ + exti_channels[num].handler = handler; + + /* Set trigger mode */ + switch (mode) { + case EXTI_RISING: + *bb_peripv(&EXTI_BASE->RTSR, num) = 1; + break; + case EXTI_FALLING: + *bb_peripv(&EXTI_BASE->FTSR, num) = 1; + break; + case EXTI_RISING_FALLING: + *bb_peripv(&EXTI_BASE->RTSR, num) = 1; + *bb_peripv(&EXTI_BASE->FTSR, num) = 1; + break; } + + /* Map num to port */ + afio_exti_select(num, port); + + /* Unmask external interrupt request */ + *bb_peripv(&EXTI_BASE->IMR, num) = 1; + + /* Enable the interrupt line */ + enable_irq(num); +} + +/** + * @brief Unregister an external interrupt handler + * @param num Number of the external interrupt line to disable. + * @see exti_num + */ +void exti_detach_interrupt(afio_exti_num num) { + /* First, mask the interrupt request */ + *bb_peripv(&EXTI_BASE->IMR, num) = 0; + + /* Then, clear the trigger selection registers */ + *bb_peripv(&EXTI_BASE->FTSR, num) = 0; + *bb_peripv(&EXTI_BASE->RTSR, num) = 0; + + /* Next, disable the IRQ, unless it's multiplexed and there are + * other active external interrupts on the same IRQ line */ + maybe_disable_irq(num); + + /* Finally, unregister the user's handler */ + exti_channels[num].handler = NULL; } -/* For EXTI0 through EXTI4, only one handler - * is associated with each channel, so we - * don't have to keep track of which channel +/* + * Interrupt handlers + */ + +static inline void clear_pending(uint32 exti_num); +static inline void dispatch_handler(uint32 exti_num); + +/* For AFIO_EXTI_0 through AFIO_EXTI_4, only one handler is associated + * with each channel, so we don't have to keep track of which channel * we came from */ void __irq_exti0(void) { - dispatch_handler(EXTI0); - clear_pending(EXTI0); + dispatch_handler(AFIO_EXTI_0); + clear_pending(AFIO_EXTI_0); } void __irq_exti1(void) { - dispatch_handler(EXTI1); - clear_pending(EXTI1); + dispatch_handler(AFIO_EXTI_1); + clear_pending(AFIO_EXTI_1); } void __irq_exti2(void) { - dispatch_handler(EXTI2); - clear_pending(EXTI2); + dispatch_handler(AFIO_EXTI_2); + clear_pending(AFIO_EXTI_2); } void __irq_exti3(void) { - dispatch_handler(EXTI3); - clear_pending(EXTI3); + dispatch_handler(AFIO_EXTI_3); + clear_pending(AFIO_EXTI_3); } void __irq_exti4(void) { - dispatch_handler(EXTI4); - clear_pending(EXTI4); + dispatch_handler(AFIO_EXTI_4); + clear_pending(AFIO_EXTI_4); } void __irq_exti9_5(void) { /* Figure out which channel it came from */ - uint32 pending; + uint32 pending = GET_BITS(EXTI_BASE->PR, 5, 9); uint32 i; - pending = REG_GET(EXTI_PR); - pending = GET_BITS(pending, 5, 9); /* Dispatch every handler if the pending bit is set */ for (i = 0; i < 5; i++) { if (pending & 0x1) { - dispatch_handler(EXTI5 + i); - clear_pending(EXTI5 + i); + dispatch_handler(AFIO_EXTI_5 + i); + clear_pending(AFIO_EXTI_5 + i); } pending >>= 1; } @@ -118,89 +192,59 @@ void __irq_exti9_5(void) { void __irq_exti15_10(void) { /* Figure out which channel it came from */ - uint32 pending; + uint32 pending = GET_BITS(EXTI_BASE->PR, 10, 15); uint32 i; - pending = REG_GET(EXTI_PR); - pending = GET_BITS(pending, 10, 15); /* Dispatch every handler if the pending bit is set */ for (i = 0; i < 6; i++) { if (pending & 0x1) { - dispatch_handler(EXTI10 + i); - clear_pending(EXTI10 + i); + dispatch_handler(AFIO_EXTI_10 + i); + clear_pending(AFIO_EXTI_10 + i); } pending >>= 1; } } - -/** - * @brief Register a handler to run upon external interrupt - * @param port source port of pin (eg EXTI_CONFIG_PORTA) - * @param pin pin number on the source port - * @param handler function handler to execute - * @param mode type of transition to trigger on +/* + * Auxiliary functions */ -void exti_attach_interrupt(uint32 port, - uint32 pin, - voidFuncPtr handler, - uint32 mode) { - static uint32 afio_regs[] = { - AFIO_EXTICR1, // EXT0-3 - AFIO_EXTICR2, // EXT4-7 - AFIO_EXTICR3, // EXT8-11 - AFIO_EXTICR4, // EXT12-15 - }; - - /* Note: All of the following code assumes that EXTI0 = 0 */ - ASSERT(EXTI0 == 0); - ASSERT(handler); - - uint32 channel = pin; - /* map port to channel */ - __write(afio_regs[pin/4], (port << ((pin % 4) * 4))); - - /* Unmask appropriate interrupt line */ - __set_bits(EXTI_IMR, BIT(channel)); - - /* Set trigger mode */ - switch (mode) { - case EXTI_RISING: - __set_bits(EXTI_RTSR, BIT(channel)); - break; - - case EXTI_FALLING: - __set_bits(EXTI_FTSR, BIT(channel)); - break; +static inline void clear_pending(uint32 exti_num) { + *bb_peripv(&EXTI_BASE->PR, exti_num) = 1; + /* If the pending bit is cleared as the last instruction in an ISR, + * it won't actually be cleared in time and the ISR will fire again. + * Insert a 2-cycle buffer to allow it to take effect. */ + asm volatile("nop"); + asm volatile("nop"); +} - case EXTI_RISING_FALLING: - __set_bits(EXTI_RTSR, BIT(channel)); - __set_bits(EXTI_FTSR, BIT(channel)); - break; +static inline void dispatch_handler(uint32 exti_num) { + ASSERT(exti_channels[exti_num].handler); + if (exti_channels[exti_num].handler) { + (exti_channels[exti_num].handler)(); } - - /* Register the handler */ - exti_channels[channel].handler = handler; - - /* Configure the enable interrupt bits for the NVIC */ - nvic_irq_enable(exti_channels[channel].irq_line); } +static inline void enable_irq(afio_exti_num exti) { + /* Maybe twiddle the IRQ bitmap for extis with multiplexed IRQs */ + if (exti > 4) { + uint16 *bitmap = exti < 10 ? &exti_9_5_en : &exti_15_10_en; + *bb_sramp(bitmap, exti) = 1; + } -/** - * @brief Unregister an external interrupt handler - * @param channel channel to disable (eg EXTI0) - */ -void exti_detach_interrupt(uint32 channel) { - ASSERT(channel < NR_EXTI_CHANNELS); - ASSERT(EXTI0 == 0); - - __clear_bits(EXTI_IMR, BIT(channel)); - __clear_bits(EXTI_FTSR, BIT(channel)); - __clear_bits(EXTI_RTSR, BIT(channel)); - - nvic_irq_disable(exti_channels[channel].irq_line); + nvic_irq_enable(exti_channels[exti].irq_line); +} - exti_channels[channel].handler = NULL; +static inline void maybe_disable_irq(afio_exti_num exti) { + if (exti > 4) { + uint16 *bitmap = exti < 10 ? &exti_9_5_en : &exti_15_10_en; + *bb_sramp(bitmap, exti) = 0; + if (*bitmap == 0) { + /* All of the external interrupts which share this IRQ + * line are disabled. */ + nvic_irq_disable(exti_channels[exti].irq_line); + } + } else { + nvic_irq_disable(exti_channels[exti].irq_line); + } } diff --git a/libmaple/exti.h b/libmaple/exti.h index 806578f..e145033 100644 --- a/libmaple/exti.h +++ b/libmaple/exti.h @@ -22,145 +22,51 @@ * THE SOFTWARE. *****************************************************************************/ - /** - * @file exti.h - * - * @brief External interrupt control prototypes and defines + * @file exti.h + * @brief External interrupt control prototypes and defines */ -#ifndef _EXTI_H_ -#define _EXTI_H_ - -/* Notes: - * - * To generate the interrupt, the interrupt line should be configured - * and enabled. This is done by programming the two trigger registers - * with the desired edge detection and by enabling the interrupt - * request by writing a '1' to the corresponding bit in the interrupt - * mask register. When the selected edge occurs on the external - * interrupt line, an interrupt request is generated. The pending bit - * corresponding to the interrupt line is also set. This request is - * reset by writing a '1' in the pending register. - * - * Hardware interrupt selection: - * - * To configure the 20 lines as interrupt sources, use the following - * procedure: - * - * 1) Configure AFIO_EXTIICR[y] to select the source input for EXTIx - * external interrupt - * 2) Configure the mask bits of the 20 interrupt lines (EXTI_IMR) - * 3) Configure the trigger selection bits of the interrupt lines - * (EXTI_RTSR and EXTI_FTSR) - * 4) Configure the enable and mask bits that control the NVIC_IRQ - * channel mapped to the External - * - * Interrupt Controller (EXTI) so that an inerrupt coming from one of - * the 20 lines can be correctly acknowledged. - * - * AFIO clock must be on. - * - * RM0008, page 107: "PD0, PD1 cannot be used for external - * interrupt/event generation on 36, 48, 64-bin packages." - * - * ---------------------------------------------------------------------------- - * Pin to EXTI Line Mappings: - * EXTI0 EXTI1 EXTI2 EXTI3 EXTI4 - * -------------------------------------------------------------------------- - * D2/PA0 D3/PA1 D1/PA2 D0/A6/PA3 D10/A10/PA4 - * D26/EXT7/PB0 D27/EXT8/PB1 D16/A2/PC2 D17/A3/PC3 D18/A4/PC4 - * D14/A0/PC0 D15/PC1 D25/EXT5/PD2 - * - * EXTI5 EXTI6 EXTI7 EXTI8 EXTI9 - * ---------------------------------------------------------------------------- - * D13/A13/PA5 D12/A12/PA6 D11/A11/PA7 D6/PA8 D7/PA9 - * D4/PB5 D5/PB6 D9/PB7 D38/PB8 D23/EXT4/PB9 - * D19/A5/PC5 D34/EXTI15/PC6 D35/EXT16/PC7 D36/PC8 D37/EXT18/PC9 - * - * EXTI10 EXTI11 EXTI12 EXTI13 EXTI14 - * ---------------------------------------------------------------------------- - * D8/PA10 D29/EXT10/PB11 D30/EXTI1/PB12 D31/EXTI12/PB13 D32/EXT13/PB14 - * D28/PB10 D20/EXTI1/PC13 D21/EXT2/PC14 - * D25/PC10 - * - * EXTI15 - * ---------------------------------------------------------------------------- - * D33/EXTI14/PB15 - * D22/EXT3/PC15 - * - * - * The 16 EXTI interrupts are mapped to 7 interrupt handlers. - * - * EXTI Lines to Interrupt Mapping: - * EXTI0 -> EXTI0 - * EXTI1 -> EXTI1 - * EXTI2 -> EXTI2 - * EXTI3 -> EXTI3 - * EXTI4 -> EXTI4 - * EXTI[5-9] -> EXT9_5 - * EXTI[10-15] -> EXT15_10 - * - * */ - -#define NR_EXTI_MODES 3 -#define NR_EXTI_CHANNELS 16 -#define NR_EXTI_PORTS NR_GPIO_PORTS // board specific +/* See notes/exti.txt for more info */ -#define EXTI_RISING 0 -#define EXTI_FALLING 1 -#define EXTI_RISING_FALLING 2 +#include "libmaple.h" +#include "gpio.h" -#define EXTI_IMR 0x40010400 // Interrupt mask register -#define EXTI_EMR (EXTI_IMR + 0x04) // Event mask register -#define EXTI_RTSR (EXTI_IMR + 0x08) // Rising trigger selection register -#define EXTI_FTSR (EXTI_IMR + 0x0C) // Falling trigger selection register -#define EXTI_SWIER (EXTI_IMR + 0x10) // Software interrupt event register -#define EXTI_PR (EXTI_IMR + 0x14) // Pending register - -#define AFIO_EVCR 0x40010000 -#define AFIO_EXTICR1 (AFIO_EVCR + 0x08) -#define AFIO_EXTICR2 (AFIO_EVCR + 0x0C) -#define AFIO_EXTICR3 (AFIO_EVCR + 0x10) -#define AFIO_EXTICR4 (AFIO_EVCR + 0x14) - -#define EXTI0 0 -#define EXTI1 1 -#define EXTI2 2 -#define EXTI3 3 -#define EXTI4 4 -#define EXTI5 5 -#define EXTI6 6 -#define EXTI7 7 -#define EXTI8 8 -#define EXTI9 9 -#define EXTI10 10 -#define EXTI11 11 -#define EXTI12 12 -#define EXTI13 13 -#define EXTI14 14 -#define EXTI15 15 - -#define EXTI_CONFIG_PORTA 0 // Maple, Maple Native, Maple Mini -#define EXTI_CONFIG_PORTB 1 // Maple, Maple Native, Maple Mini -#define EXTI_CONFIG_PORTC 2 // Maple, Maple Native, Maple Mini -#define EXTI_CONFIG_PORTD 3 // Maple and Maple Native only -#define EXTI_CONFIG_PORTE 4 // Native only -#define EXTI_CONFIG_PORTF 5 // Native only -#define EXTI_CONFIG_PORTG 6 // Native only +#ifndef _EXTI_H_ +#define _EXTI_H_ #ifdef __cplusplus extern "C"{ #endif -void exti_attach_interrupt(uint32 port, uint32 pin, voidFuncPtr handler, - uint32 mode); -void exti_detach_interrupt(uint32 channel); +/** EXTI register map type */ +typedef struct exti_reg_map { + __io uint32 IMR; /**< Interrupt mask register */ + __io uint32 EMR; /**< Event mask register */ + __io uint32 RTSR; /**< Rising trigger selection register */ + __io uint32 FTSR; /**< Falling trigger selection register */ + __io uint32 SWIER; /**< Software interrupt event register */ + __io uint32 PR; /**< Pending register */ +} exti_reg_map; + +/** EXTI register map base pointer */ +#define EXTI_BASE ((exti_reg_map*)0x40010400) + +/** External interrupt trigger mode */ +typedef enum exti_trigger_mode { + EXTI_RISING, /**< Trigger on the rising edge */ + EXTI_FALLING, /**< Trigger on the falling edge */ + EXTI_RISING_FALLING /**< Trigger on both the rising and falling edges */ +} exti_trigger_mode; + +void exti_attach_interrupt(afio_exti_num num, + afio_exti_port port, + voidFuncPtr handler, + exti_trigger_mode mode); +void exti_detach_interrupt(afio_exti_num num); #ifdef __cplusplus } // extern "C" #endif - #endif - diff --git a/libmaple/fsmc.c b/libmaple/fsmc.c index 49526f4..1561add 100644 --- a/libmaple/fsmc.c +++ b/libmaple/fsmc.c @@ -31,6 +31,8 @@ #include "gpio.h" #include "fsmc.h" +#ifdef STM32_HIGH_DENSITY + /* These values determined for a particular SRAM chip by following the * calculations in the ST FSMC application note. */ #define FSMC_ADDSET 0x0 @@ -45,55 +47,55 @@ void fsmc_native_sram_init(void) { /* First we setup all the GPIO pins. */ /* Data lines... */ - gpio_set_mode(GPIOD_BASE, 0, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOD_BASE, 1, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOD_BASE, 8, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOD_BASE, 9, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOD_BASE, 10, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOD_BASE, 14, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOD_BASE, 15, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 7, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 8, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 9, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 10, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 11, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 12, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 13, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 14, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOE_BASE, 15, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 0, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 8, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 9, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 10, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 14, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 15, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 7, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 8, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 9, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 10, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 11, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 12, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 13, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 14, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOE, 15, GPIO_AF_OUTPUT_PP); /* Address lines... */ - gpio_set_mode(GPIOD_BASE, 11, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOD_BASE, 12, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOD_BASE, 13, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 0, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 1, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 2, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 3, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 4, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 5, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 12, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 13, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 14, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOF_BASE, 15, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOG_BASE, 0, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOG_BASE, 1, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOG_BASE, 2, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOG_BASE, 3, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOG_BASE, 4, MODE_AF_OUTPUT_PP); - gpio_set_mode(GPIOG_BASE, 5, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 11, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 12, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOD, 13, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 0, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 1, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 2, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 3, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 4, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 5, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 12, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 13, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 14, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOF, 15, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 0, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 1, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 2, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 3, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 4, GPIO_AF_OUTPUT_PP); + gpio_set_mode(GPIOG, 5, GPIO_AF_OUTPUT_PP); /* And control lines... */ - gpio_set_mode(GPIOD_BASE, 4, MODE_AF_OUTPUT_PP); // NOE - gpio_set_mode(GPIOD_BASE, 5, MODE_AF_OUTPUT_PP); // NWE + gpio_set_mode(GPIOD, 4, GPIO_AF_OUTPUT_PP); // NOE + gpio_set_mode(GPIOD, 5, GPIO_AF_OUTPUT_PP); // NWE - gpio_set_mode(GPIOD_BASE, 7, MODE_AF_OUTPUT_PP); // NE1 - gpio_set_mode(GPIOG_BASE, 9, MODE_AF_OUTPUT_PP); // NE2 - gpio_set_mode(GPIOG_BASE, 10, MODE_AF_OUTPUT_PP); // NE3 - gpio_set_mode(GPIOG_BASE, 12, MODE_AF_OUTPUT_PP); // NE4 + gpio_set_mode(GPIOD, 7, GPIO_AF_OUTPUT_PP); // NE1 + gpio_set_mode(GPIOG, 9, GPIO_AF_OUTPUT_PP); // NE2 + gpio_set_mode(GPIOG, 10, GPIO_AF_OUTPUT_PP); // NE3 + gpio_set_mode(GPIOG, 12, GPIO_AF_OUTPUT_PP); // NE4 - gpio_set_mode(GPIOE_BASE, 0, MODE_AF_OUTPUT_PP); // NBL0 - gpio_set_mode(GPIOE_BASE, 1, MODE_AF_OUTPUT_PP); // NBL1 + gpio_set_mode(GPIOE, 0, GPIO_AF_OUTPUT_PP); // NBL0 + gpio_set_mode(GPIOE, 1, GPIO_AF_OUTPUT_PP); // NBL1 /* Next enable the clock */ rcc_clk_enable(RCC_FSMC); @@ -132,3 +134,4 @@ void fsmc_native_sram_init(void) { /* (FSMC_BWTR3 not used for this simple configuration.) */ } +#endif /* STM32_HIGH_DENSITY */ diff --git a/libmaple/fsmc.h b/libmaple/fsmc.h index e83b529..fed6894 100644 --- a/libmaple/fsmc.h +++ b/libmaple/fsmc.h @@ -37,6 +37,8 @@ extern "C"{ #endif +#ifdef STM32_HIGH_DENSITY + // There are 4 FSMC chip-select devices; here are the SRAM-specific registers // for each @@ -82,9 +84,10 @@ typedef struct { void fsmc_native_sram_init(void); +#endif /* STM32_HIGH_DENSITY */ + #ifdef __cplusplus } // extern "C" #endif - #endif diff --git a/libmaple/gpio.c b/libmaple/gpio.c index 71e5230..b08be12 100644 --- a/libmaple/gpio.c +++ b/libmaple/gpio.c @@ -26,44 +26,151 @@ * @brief GPIO initialization routine */ -#include "libmaple.h" -#include "rcc.h" #include "gpio.h" +#include "rcc.h" + +/* + * GPIO devices + */ + +static gpio_dev gpioa = { + .regs = GPIOA_BASE, + .clk_id = RCC_GPIOA +}; +/** GPIO port A device. */ +gpio_dev *GPIOA = &gpioa; + +static gpio_dev gpiob = { + .regs = GPIOB_BASE, + .clk_id = RCC_GPIOB +}; +/** GPIO port B device. */ +gpio_dev *GPIOB = &gpiob; + +static gpio_dev gpioc = { + .regs = GPIOC_BASE, + .clk_id = RCC_GPIOC +}; +/** GPIO port C device. */ +gpio_dev *GPIOC = &gpioc; + +static gpio_dev gpiod = { + .regs = GPIOD_BASE, + .clk_id = RCC_GPIOD +}; +/** GPIO port D device. */ +gpio_dev *GPIOD = &gpiod; + +#ifdef STM32_HIGH_ +static gpio_dev gpioe = { + .regs = GPIOE_BASE, + .clk_id = RCC_GPIOE +}; +/** GPIO port E device. */ +gpio_dev *GPIOE = &gpioe; + +static gpio_dev gpiof = { + .regs = GPIOF_BASE, + .clk_id = RCC_GPIOF +}; +/** GPIO port F device. */ +gpio_dev *GPIOF = &gpiof; -void gpio_init(void) { - rcc_clk_enable(RCC_GPIOA); - rcc_clk_enable(RCC_GPIOB); - rcc_clk_enable(RCC_GPIOC); -#if NR_GPIO_PORTS >= 4 /* Maple, but not Maple Mini */ - rcc_clk_enable(RCC_GPIOD); -#elif NR_GPIO_PORTS >= 7 /* Maple Native (high density only) */ - rcc_clk_enable(RCC_GPIOE); - rcc_clk_enable(RCC_GPIOF); - rcc_clk_enable(RCC_GPIOG); +static gpio_dev gpiog = { + .regs = GPIOG_BASE, + .clk_id = RCC_GPIOG +}; +/** GPIO port G device. */ +gpio_dev *GPIOG = &gpiog; #endif - rcc_clk_enable(RCC_AFIO); + +/* + * GPIO convenience routines + */ + +/** + * Initialize a GPIO device. + * + * Enables the clock for and resets the given device. + * + * @param dev GPIO device to initialize. + */ +void gpio_init(gpio_dev *dev) { + rcc_clk_enable(dev->clk_id); + rcc_reset_dev(dev->clk_id); } -void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, GPIOPinMode mode) { - uint32 tmp; - uint32 shift = POS(gpio_pin % 8); - GPIOReg CR; +/** + * Initialize and reset all available GPIO devices. + */ +void gpio_init_all(void) { + gpio_init(GPIOA); + gpio_init(GPIOB); + gpio_init(GPIOC); + gpio_init(GPIOD); +#ifdef STM32_HIGH_DENSITY + gpio_init(GPIOE); + gpio_init(GPIOF); + gpio_init(GPIOG); +#endif +} - ASSERT(port); - ASSERT(gpio_pin < 16); +/** + * Set the mode of a GPIO pin. + * + * @param dev GPIO device. + * @param pin Pin on the device whose mode to set, 0--15. + * @param mode General purpose or alternate function mode to set the pin to. + * @see gpio_pin_mode + */ +void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode) { + gpio_reg_map *regs = dev->regs; + __io uint32 *cr = ®s->CRL + (pin >> 3); + uint32 shift = (pin & 0x7) * 4; + uint32 tmp = *cr; + + tmp &= ~(0xF << shift); + tmp |= (mode == GPIO_INPUT_PU ? GPIO_INPUT_PD : mode) << shift; + *cr = tmp; - if (mode == GPIO_MODE_INPUT_PU) { - port->ODR |= BIT(gpio_pin); - mode = CNF_INPUT_PD; - } else if (mode == GPIO_MODE_INPUT_PD) { - port->ODR &= ~BIT(gpio_pin); + if (mode == GPIO_INPUT_PD) { + regs->ODR &= ~BIT(pin); + } else if (mode == GPIO_INPUT_PU) { + regs->ODR |= BIT(pin); } +} + +/* + * AFIO + */ - CR = (gpio_pin < 8) ? &(port->CRL) : &(port->CRH); +/** + * Initialize the AFIO clock, and reset the AFIO registers. + */ +void afio_init(void) { + rcc_clk_enable(RCC_AFIO); + rcc_reset_dev(RCC_AFIO); +} - tmp = *CR; - tmp &= POS_MASK(shift); - tmp |= mode << shift; +#define AFIO_EXTI_SEL_MASK 0xF + +/** + * Select a source input for an external interrupt. + * + * @param exti External interrupt. One of: AFIO_EXTI_0, + * AFIO_EXTI_1, ..., AFIO_EXTI_15. + * @param gpio_port Port which contains pin to use as source input. + * One of: AFIO_EXTI_PA, AFIO_EXTI_PB, AFIO_EXTI_PC, + * AFIO_EXTI_PD, and, on high density devices, + * AFIO_EXTI_PE, AFIO_EXTI_PF, AFIO_EXTI_PG. + * @see exti_port + */ +void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port) { + __io uint32 *exti_cr = &AFIO_BASE->EXTICR1 + exti / 4; + uint32 shift = 4 * (exti % 4); + uint32 cr = *exti_cr; - *CR = tmp; + cr &= ~(AFIO_EXTI_SEL_MASK << shift); + cr |= gpio_port << shift; + *exti_cr = cr; } diff --git a/libmaple/gpio.h b/libmaple/gpio.h index 53f77c4..48dbc00 100644 --- a/libmaple/gpio.h +++ b/libmaple/gpio.h @@ -3,126 +3,331 @@ * * Copyright (c) 2010 Perry Hung. * - * 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 + * 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 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. *****************************************************************************/ /** * @file gpio.h * - * @brief GPIO prototypes, defines, and inlined access functions + * @brief General purpose I/0 (GPIO) and Alternate Function I/O + * (AFIO) prototypes, defines, and inlined access functions. */ -#ifndef _GPIO_H -#define _GPIO_H - -/* Each of the GPIO port bits can be in the following modes (STM32 138/995): - * Input floating - * Input pull-up - * Input pull-down - * Analog Input - * Output open-drain - * Output push-pull - * Alternate function push-pull - * Alternate function open-drain - * - * - After reset, the alternate functions are not active and IO prts - * are set to Input Floating mode, EXCEPT for the Serial Wire and JTAG - * ports, which are in alternate function mode by default. */ - -#define AFIO_MAPR ((volatile uint32*)0x40010004) - -#define GPIOA_BASE ((GPIO_Port*)0x40010800) -#define GPIOB_BASE ((GPIO_Port*)0x40010C00) -#define GPIOC_BASE ((GPIO_Port*)0x40011000) -#define GPIOD_BASE ((GPIO_Port*)0x40011400) -#define GPIOE_BASE ((GPIO_Port*)0x40011800) // High-density devices only -#define GPIOF_BASE ((GPIO_Port*)0x40011C00) // High-density devices only -#define GPIOG_BASE ((GPIO_Port*)0x40012000) // High-density devices only - -#define GPIO_SPEED_50MHZ (0x3) - -#define MODE_OUTPUT_PP ((0x00 << 2) | GPIO_SPEED_50MHZ) -#define MODE_OUTPUT_OD ((0x01 << 2) | GPIO_SPEED_50MHZ) -#define MODE_AF_OUTPUT_PP ((0x02 << 2) | GPIO_SPEED_50MHZ) -#define MODE_AF_OUTPUT_OD ((0x03 << 2) | GPIO_SPEED_50MHZ) - -#define CNF_INPUT_ANALOG (0x00 << 2) -#define CNF_INPUT_FLOATING (0x01 << 2) -#define CNF_INPUT_PD (0x02 << 2) -#define CNF_INPUT_PU (0x02 << 2) - -typedef enum GPIOPinMode { - GPIO_MODE_OUTPUT_PP = MODE_OUTPUT_PP, - GPIO_MODE_OUTPUT_OD = MODE_OUTPUT_OD, - GPIO_MODE_AF_OUTPUT_PP = MODE_AF_OUTPUT_PP, - GPIO_MODE_AF_OUTPUT_OD = MODE_AF_OUTPUT_OD, - GPIO_MODE_INPUT_ANALOG = CNF_INPUT_ANALOG, - GPIO_MODE_INPUT_FLOATING = CNF_INPUT_FLOATING, - GPIO_MODE_INPUT_PD = CNF_INPUT_PD, - GPIO_MODE_INPUT_PU, -} GPIOPinMode; - -typedef struct { - volatile uint32 CRL; // Port configuration register low - volatile uint32 CRH; // Port configuration register high - volatile uint32 IDR; // Port input data register - volatile uint32 ODR; // Port output data register - volatile uint32 BSRR; // Port bit set/reset register - volatile uint32 BRR; // Port bit reset register - volatile uint32 LCKR; // Port configuration lock register -} GPIO_Port; - -typedef volatile uint32* GPIOReg; - -#define POS_MASK(shift) (~(0xF << shift)) -#define POS(val) (val << 2) +#ifndef _GPIO_H_ +#define _GPIO_H_ + +#include "libmaple.h" +#include "rcc.h" #ifdef __cplusplus extern "C"{ #endif -void gpio_init(void); -void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, GPIOPinMode mode); +/* + * GPIO register maps and devices + */ + +/** GPIO register map type */ +typedef struct gpio_reg_map { + __io uint32 CRL; ///< Port configuration register low + __io uint32 CRH; ///< Port configuration register high + __io uint32 IDR; ///< Port input data register + __io uint32 ODR; ///< Port output data register + __io uint32 BSRR; ///< Port bit set/reset register + __io uint32 BRR; ///< Port bit reset register + __io uint32 LCKR; ///< Port configuration lock register +} gpio_reg_map; + +/** GPIO device type */ +typedef struct gpio_dev { + gpio_reg_map *regs; ///< Register map + rcc_clk_id clk_id; ///< RCC clock information +} gpio_dev; + +/** GPIO port A device */ +extern gpio_dev *GPIOA; +/** GPIO port B device */ +extern gpio_dev *GPIOB; +/** GPIO port C device */ +extern gpio_dev *GPIOC; +/** GPIO port D device */ +extern gpio_dev *GPIOD; +#ifdef STM32_HIGH_DENSITY +/** GPIO port E device */ +extern gpio_dev *GPIOE; +/** GPIO port F device */ +extern gpio_dev *GPIOF; +/** GPIO port G device */ +extern gpio_dev *GPIOG; +#endif + +/** GPIO port A register map base pointer */ +#define GPIOA_BASE ((gpio_reg_map*)0x40010800) +/** GPIO port B register map base pointer */ +#define GPIOB_BASE ((gpio_reg_map*)0x40010C00) +/** GPIO port C register map base pointer */ +#define GPIOC_BASE ((gpio_reg_map*)0x40011000) +/** GPIO port D register map base pointer */ +#define GPIOD_BASE ((gpio_reg_map*)0x40011400) +#ifdef STM32_HIGH_DENSITY +/** GPIO port E register map base pointer */ +#define GPIOE_BASE ((gpio_reg_map*)0x40011800) +/** GPIO port F register map base pointer */ +#define GPIOF_BASE ((gpio_reg_map*)0x40011C00) +/** GPIO port G register map base pointer */ +#define GPIOG_BASE ((gpio_reg_map*)0x40012000) +#endif + +/* + * GPIO register bit definitions + */ + +/* Control registers, low and high */ +#define GPIO_CR_CNF_INPUT_ANALOG (0x0 << 2) +#define GPIO_CR_CNF_INPUT_FLOATING (0x1 << 2) +#define GPIO_CR_CNF_INPUT_PU_PD (0x2 << 2) +#define GPIO_CR_CNF_OUTPUT_PP (0x0 << 2) +#define GPIO_CR_CNF_OUTPUT_OD (0x1 << 2) +#define GPIO_CR_CNF_AF_OUTPUT_PP (0x2 << 2) +#define GPIO_CR_CNF_AF_OUTPUT_OD (0x3 << 2) +#define GPIO_CR_MODE_INPUT 0x0 +#define GPIO_CR_MODE_OUTPUT_10MHZ 0x1 +#define GPIO_CR_MODE_OUTPUT_2MHZ 0x2 +#define GPIO_CR_MODE_OUTPUT_50MHZ 0x3 + +/** GPIO Pin modes. These only allow for 50MHZ max output speeds; if + * you want slower, use direct register access. */ +typedef enum gpio_pin_mode { + GPIO_OUTPUT_PP = (GPIO_CR_CNF_OUTPUT_PP | + GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output push-pull. */ + GPIO_OUTPUT_OD = (GPIO_CR_CNF_OUTPUT_OD | + GPIO_CR_MODE_OUTPUT_50MHZ), /**< Output open-drain. */ + GPIO_AF_OUTPUT_PP = (GPIO_CR_CNF_AF_OUTPUT_PP | + GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function + output push-pull. */ + GPIO_AF_OUTPUT_OD = (GPIO_CR_CNF_AF_OUTPUT_OD | + GPIO_CR_MODE_OUTPUT_50MHZ), /**< Alternate function + output open drain. */ + GPIO_INPUT_ANALOG = (GPIO_CR_CNF_INPUT_ANALOG | + GPIO_CR_MODE_INPUT), /**< Analog input. */ + GPIO_INPUT_FLOATING = (GPIO_CR_CNF_INPUT_FLOATING | + GPIO_CR_MODE_INPUT), /**< Input floating. */ + GPIO_INPUT_PD = (GPIO_CR_CNF_INPUT_PU_PD | + GPIO_CR_MODE_INPUT), /**< Input pull-down. */ + GPIO_INPUT_PU /**< Input pull-up. */ + /* GPIO_INPUT_PU treated as a special case, for ODR twiddling */ +} gpio_pin_mode; -static inline void gpio_write_bit(GPIO_Port *port, uint8 gpio_pin, uint8 val) { - if (val){ - port->BSRR = BIT(gpio_pin); +/* + * GPIO Convenience routines + */ + +void gpio_init(gpio_dev *dev); +void gpio_init_all(void); +void gpio_set_mode(gpio_dev *dev, uint8 pin, gpio_pin_mode mode); + +/** + * Set or reset a GPIO pin. + * + * Pin must have previously been configured to output mode. + * + * @param dev GPIO device whose pin to set. + * @param pin Pin on to set or reset + * @param val If true, set the pin. If false, reset the pin. + */ +static inline void gpio_write_bit(gpio_dev *dev, uint8 pin, uint8 val) { + if (val) { + dev->regs->BSRR = BIT(pin); } else { - port->BRR = BIT(gpio_pin); + dev->regs->BRR = BIT(pin); } } -static inline uint32 gpio_read_bit(GPIO_Port *port, uint8 gpio_pin) { - return (port->IDR & BIT(gpio_pin) ? 1 : 0); +/** + * Determine whether or not a GPIO pin is set. + * + * Pin must have previously been configured to input mode. + * + * @param dev GPIO device whose pin to test. + * @param pin Pin on dev to test. + * @return True if the pin is set, false otherwise. + */ +static inline uint32 gpio_read_bit(gpio_dev *dev, uint8 pin) { + return dev->regs->IDR & BIT(pin); } -/* For pins configured as output push-pull, reading the ODR returns - * the last value written in push-pull mode. +/** + * Toggle a pin configured as output push-pull. + * @param dev GPIO device. + * @param pin Pin on dev to toggle. */ -static inline void gpio_toggle_pin(GPIO_Port *port, uint8 gpio_pin) { - port->ODR = port->ODR ^ BIT(gpio_pin); +static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) { + dev->regs->ODR = dev->regs->ODR ^ BIT(pin); } -#ifdef __cplusplus -} // extern "C" +/* + * AFIO register map + */ + +/** AFIO register map */ +typedef struct afio_reg_map { + __io uint32 EVCR; /**< Event control register. */ + __io uint32 MAPR; /**< AF remap and debug I/O configuration + register. */ + __io uint32 EXTICR1; /**< External interrupt configuration + register 1. */ + __io uint32 EXTICR2; /**< External interrupt configuration + register 2. */ + __io uint32 EXTICR3; /**< External interrupt configuration + register 3. */ + __io uint32 EXTICR4; /**< External interrupt configuration + register 4. */ + __io uint32 MAPR2; /**< AF remap and debug I/O configuration + register 2. */ +} afio_reg_map; + +/** AFIO register map base pointer. */ +#define AFIO_BASE ((afio_reg_map *)0x40010000) + +/* + * AFIO register bit definitions + */ + +/* Event control register */ +#define AFIO_EVCR_EVOE (0x1 << 7) +#define AFIO_EVCR_PORT_PA (0x0 << 4) +#define AFIO_EVCR_PORT_PB (0x1 << 4) +#define AFIO_EVCR_PORT_PC (0x2 << 4) +#define AFIO_EVCR_PORT_PD (0x3 << 4) +#define AFIO_EVCR_PORT_PE (0x4 << 4) +#define AFIO_EVCR_PIN_0 0x0 +#define AFIO_EVCR_PIN_1 0x1 +#define AFIO_EVCR_PIN_2 0x2 +#define AFIO_EVCR_PIN_3 0x3 +#define AFIO_EVCR_PIN_4 0x4 +#define AFIO_EVCR_PIN_5 0x5 +#define AFIO_EVCR_PIN_6 0x6 +#define AFIO_EVCR_PIN_7 0x7 +#define AFIO_EVCR_PIN_8 0x8 +#define AFIO_EVCR_PIN_9 0x9 +#define AFIO_EVCR_PIN_10 0xA +#define AFIO_EVCR_PIN_11 0xB +#define AFIO_EVCR_PIN_12 0xC +#define AFIO_EVCR_PIN_13 0xD +#define AFIO_EVCR_PIN_14 0xE +#define AFIO_EVCR_PIN_15 0xF + +/* AF remap and debug I/O configuration register */ +#define AFIO_MAPR_SWJ_FULL_SWJ (0x0 << 24) +#define AFIO_MAPR_SWJ_FULL_SWJ_NO_NJRST (0x1 << 24) +#define AFIO_MAPR_SWJ_NO_JTAG_SW (0x2 << 24) +#define AFIO_MAPR_SWJ_NO_JTAG_NO_SW (0x4 << 24) +#define AFIO_MAPR_ADC2_ETRGREG_REMAP BIT(20) +#define AFIO_MAPR_ADC2_ETRGINJ_REMAP BIT(19) +#define AFIO_MAPR_ADC1_ETRGREG_REMAP BIT(18) +#define AFIO_MAPR_ADC1_ETRGINJ_REMAP BIT(17) +#define AFIO_MAPR_TIM5CH4_IREMAP BIT(16) +#define AFIO_MAPR_PD01_REMAP BIT(15) +#define AFIO_MAPR_CAN_REMAP (BIT(14) | BIT(13)) +#define AFIO_MAPR_TIM4_REMAP_FULL BIT(12) +#define AFIO_MAPR_TIM3_REMAP (BIT(11) | BIT(10)) +#define AFIO_MAPR_TIM2_REMAP (BIT(9) | BIT(8)) +#define AFIO_MAPR_TIM1_REMAP (BIT(7) | BIT(6)) +#define AFIO_MAPR_USART3_REMAP (BIT(5) | BIT(4)) +#define AFIO_MAPR_USART2_REMAP BIT(3) +#define AFIO_MAPR_USART1_REMAP BIT(2) +#define AFIO_MAPR_I2C1_REMAP BIT(1) +#define AFIO_MAPR_SPI1_REMAP BIT(0) + +/* External interrupt configuration registers */ + +/** + * External interrupt line port selector. Used to determine which + * GPIO port to map an external interrupt line onto. */ +typedef enum { + AFIO_EXTI_PA, /**< Use PAx pin. */ + AFIO_EXTI_PB, /**< Use PBx pin. */ + AFIO_EXTI_PC, /**< Use PCx pin. */ + AFIO_EXTI_PD, /**< Use PDx pin. */ +#ifdef STM32_HIGH_DENSITY + AFIO_EXTI_PE, /**< Use PEx pin. */ + AFIO_EXTI_PF, /**< Use PFx pin. */ + AFIO_EXTI_PG, /**< Use PGx pin. */ #endif +} afio_exti_port; + +/** + * External interrupt line numbers. + */ +typedef enum { + AFIO_EXTI_0, /**< External interrupt line 0. */ + AFIO_EXTI_1, /**< External interrupt line 1. */ + AFIO_EXTI_2, /**< External interrupt line 2. */ + AFIO_EXTI_3, /**< External interrupt line 3. */ + AFIO_EXTI_4, /**< External interrupt line 4. */ + AFIO_EXTI_5, /**< External interrupt line 5. */ + AFIO_EXTI_6, /**< External interrupt line 6. */ + AFIO_EXTI_7, /**< External interrupt line 7. */ + AFIO_EXTI_8, /**< External interrupt line 8. */ + AFIO_EXTI_9, /**< External interrupt line 9. */ + AFIO_EXTI_10, /**< External interrupt line 10. */ + AFIO_EXTI_11, /**< External interrupt line 11. */ + AFIO_EXTI_12, /**< External interrupt line 12. */ + AFIO_EXTI_13, /**< External interrupt line 13. */ + AFIO_EXTI_14, /**< External interrupt line 14. */ + AFIO_EXTI_15, /**< External interrupt line 15. */ +} afio_exti_num; +/* AF remap and debug I/O configuration register 2 */ +#define AFIO_MAPR2_FSMC_NADV BIT(10) +#define AFIO_MAPR2_TIM14_REMAP BIT(9) +#define AFIO_MAPR2_TIM13_REMAP BIT(8) +#define AFIO_MAPR2_TIM11_REMAP BIT(7) +#define AFIO_MAPR2_TIM10_REMAP BIT(6) +#define AFIO_MAPR2_TIM9_REMAP BIT(5) + +/* + * AFIO convenience routines + */ + +void afio_init(void); +void afio_exti_select(afio_exti_num exti, afio_exti_port gpio_port); + +/** + * Set the SWJ_CONFIG bits in the AFIO MAPR register. + * + * @param config Desired SWJ_CONFIG bits setting. One of: + * AFIO_MAPR_SWJ_FULL_SWJ (full SWJ), + * AFIO_MAPR_SWJ_FULL_SWJ_NO_NJRST (full SWJ, no NJTRST), + * AFIO_MAPR_SWJ_NO_JTAG_SW (JTAG-DP disabled, SW-DP enabled), + * AFIO_MAPR_SWJ_NO_JTAG_NO_SW (JTAG-DP and SW-DP both disabled). + */ +static inline void afio_mapr_swj_config(uint32 config) { + __io uint32 *mapr = &AFIO_BASE->MAPR; + *mapr = (*mapr & ~(0x7 << 24)) | config; +} + +#ifdef __cplusplus +} +#endif #endif diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h index 6b75c96..0bbd34e 100644 --- a/libmaple/libmaple.h +++ b/libmaple/libmaple.h @@ -36,7 +36,7 @@ /* * Where to put usercode, based on space reserved for bootloader. * - * FIXME this has no business being here + * FIXME this has no business being here */ #define USER_ADDR_ROM 0x08005000 #define USER_ADDR_RAM 0x20000C00 diff --git a/libmaple/libmaple_types.h b/libmaple/libmaple_types.h index a976a9e..54bef65 100644 --- a/libmaple/libmaple_types.h +++ b/libmaple/libmaple_types.h @@ -44,6 +44,7 @@ typedef long long int64; typedef void (*voidFuncPtr)(void); #define __io volatile +#define __attr_flash __attribute__((section (".USER_FLASH"))) #ifndef NULL #define NULL 0 diff --git a/libmaple/pwr.h b/libmaple/pwr.h index 5ff815d..5f68c34 100644 --- a/libmaple/pwr.h +++ b/libmaple/pwr.h @@ -41,20 +41,19 @@ typedef struct pwr_reg_map { __io uint32 CSR; /**< Control and status register */ } pwr_reg_map; -/* - * Power peripheral base. - */ +/** Power peripheral register map base pointer. */ #define PWR_BASE ((pwr_reg_map*)0x40007000) -/** Power interface device. */ +/** Power device type. */ typedef struct pwr_dev { - pwr_reg_map *regs; + pwr_reg_map *regs; /**< Register map */ } pwr_dev; /** * Power device. */ extern const pwr_dev *PWR; + /* * Register bit definitions */ diff --git a/libmaple/rcc.h b/libmaple/rcc.h index 410ab8b..8697e01 100644 --- a/libmaple/rcc.h +++ b/libmaple/rcc.h @@ -27,6 +27,8 @@ * @brief reset and clock control definitions and prototypes */ +#include "libmaple_types.h" + #ifndef _RCC_H_ #define _RCC_H_ @@ -182,7 +184,6 @@ typedef enum { RCC_BKP, } rcc_clk_id; - void rcc_clk_init(uint32 sysclk_src, uint32 pll_src, uint32 pll_mul); void rcc_clk_enable(rcc_clk_id device); void rcc_reset_dev(rcc_clk_id device); diff --git a/libmaple/ring_buffer.h b/libmaple/ring_buffer.h index a44088e..f7baa6c 100644 --- a/libmaple/ring_buffer.h +++ b/libmaple/ring_buffer.h @@ -13,21 +13,20 @@ extern "C"{ #endif -/* The buffer is empty when head == tail. +/** + * Ring buffer type. + * + * The buffer is empty when head == tail. * * The buffer is full when the head is one byte in front of the tail, * modulo buffer length. * * One byte is left free to distinguish empty from full. */ typedef struct ring_buffer { - /** Buffer items are stored into */ - volatile uint8 *buf; - /** Index of the next item to remove */ - uint16 head; - /** Index where the next item will get inserted */ - uint16 tail; - /** Buffer capacity minus one */ - uint16 size; + volatile uint8 *buf; /**< Buffer items are stored into */ + uint16 head; /**< Index of the next item to remove */ + uint16 tail; /**< Index where the next item will get inserted */ + uint16 size; /**< Buffer capacity minus one */ } ring_buffer; /** diff --git a/libmaple/spi.c b/libmaple/spi.c index 8bba0d6..7bdc18a 100644 --- a/libmaple/spi.c +++ b/libmaple/spi.c @@ -43,23 +43,23 @@ typedef struct spi_dev { SPI *base; - GPIO_Port *port; + gpio_dev *gpio_d; uint8 sck_pin; uint8 miso_pin; uint8 mosi_pin; } spi_dev; -static const spi_dev spi_dev1 = { +spi_dev spi_dev1 = { .base = (SPI*)SPI1_BASE, - .port = GPIOA_BASE, + .gpio_d = NULL, .sck_pin = 5, .miso_pin = 6, .mosi_pin = 7 }; -static const spi_dev spi_dev2 = { +spi_dev spi_dev2 = { .base = (SPI*)SPI2_BASE, - .port = GPIOB_BASE, + .gpio_d = NULL, .sck_pin = 13, .miso_pin = 14, .mosi_pin = 15 @@ -90,11 +90,13 @@ void spi_init(uint32 spi_num, ASSERT(prescale != CR1_BR_PRESCALE_2); spi = (SPI*)SPI1_BASE; rcc_clk_enable(RCC_SPI1); + spi_dev1.gpio_d = GPIOA; spi_gpio_cfg(&spi_dev1); break; case 2: spi = (SPI*)SPI2_BASE; rcc_clk_enable(RCC_SPI2); + spi_dev1.gpio_d = GPIOB, spi_gpio_cfg(&spi_dev2); break; } @@ -155,7 +157,7 @@ uint8 spi_tx(uint32 spi_num, uint8 *buf, uint32 len) { } static void spi_gpio_cfg(const spi_dev *dev) { - gpio_set_mode(dev->port, dev->sck_pin, GPIO_MODE_AF_OUTPUT_PP); - gpio_set_mode(dev->port, dev->miso_pin, GPIO_MODE_AF_OUTPUT_PP); - gpio_set_mode(dev->port, dev->mosi_pin, GPIO_MODE_AF_OUTPUT_PP); + gpio_set_mode(dev->gpio_d, dev->sck_pin, GPIO_AF_OUTPUT_PP); + gpio_set_mode(dev->gpio_d, dev->miso_pin, GPIO_AF_OUTPUT_PP); + gpio_set_mode(dev->gpio_d, dev->mosi_pin, GPIO_AF_OUTPUT_PP); } diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c index 62f56fc..2fc4eb2 100644 --- a/libmaple/usb/usb.c +++ b/libmaple/usb/usb.c @@ -44,7 +44,7 @@ volatile uint32 bDeviceState = UNCONNECTED; volatile uint16 wIstr = 0; -volatile bIntPackSOF = 0; +volatile uint32 bIntPackSOF = 0; DEVICE Device_Table = {NUM_ENDPTS, @@ -99,15 +99,13 @@ struct { } ResumeS; void setupUSB (void) { - gpio_set_mode(USB_DISC_BANK, - USB_DISC_PIN, - GPIO_MODE_OUTPUT_PP); + gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); /* setup the apb1 clock for USB */ pRCC->APB1ENR |= 0x00800000; /* initialize the usb application */ - gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 0); // presents us to the host + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 0); // presents us to the host USB_Init(); // low level init routine provided by the ST library } @@ -115,7 +113,7 @@ void disableUSB (void) { // These are just guesses about how to do this // TODO: real disable function usbDsbISR(); - gpio_write_bit(USB_DISC_BANK,USB_DISC_PIN,1); + gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); } void usbSuspend(void) { @@ -320,8 +318,29 @@ if (wIstr & ISTR_CTR & wInterrupt_Mask) { } +static void FIXME_delayMicroseconds_copy(uint32 us) { + /* So (2^32)/12 micros max, or less than 6 minutes */ + us *= 12; + + /* fudge for function call overhead */ + us--; + asm volatile(" mov r0, %[us] \n\t" + "1: subs r0, #1 \n\t" + " bhi 1b \n\t" + : + : [us] "r" (us) + : "r0"); +} + +static void FIXME_delay_copy(unsigned long ms) { + uint32 i; + for (i = 0; i < ms; i++) { + FIXME_delayMicroseconds_copy(1000); + } +} + void usbWaitReset(void) { - delay(RESET_DELAY); + FIXME_delay_copy(RESET_DELAY); systemHardReset(); } diff --git a/libmaple/usb/usb_callbacks.c b/libmaple/usb/usb_callbacks.c index ccb0fdd..8184537 100644 --- a/libmaple/usb/usb_callbacks.c +++ b/libmaple/usb/usb_callbacks.c @@ -129,7 +129,7 @@ u8* vcomGetSetLineCoding(uint16 length) { return (uint8*)&line_coding; } -vcomSetLineState(void) { +void vcomSetLineState(void) { } void usbInit(void) { diff --git a/libmaple/usb/usb_config.h b/libmaple/usb/usb_config.h index 394c580..9003da9 100644 --- a/libmaple/usb/usb_config.h +++ b/libmaple/usb/usb_config.h @@ -4,6 +4,7 @@ #define __USB_CONFIG_H #include "usb_lib.h" +#include "gpio.h" /****************************************************************************** ****************************************************************************** @@ -31,19 +32,19 @@ /* USB Identifier numbers */ #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_BANK GPIOC_BASE + #define USB_DISC_DEV GPIOC #define USB_DISC_PIN 12 #elif defined(BOARD_maple_mini) #define VCOM_ID_PRODUCT 0x0005 - #define USB_DISC_BANK GPIOB_BASE + #define USB_DISC_DEV GPIOB #define USB_DISC_PIN 9 #elif defined(BOARD_maple_native) #define VCOM_ID_PRODUCT 0x0006 - #define USB_DISC_BANK GPIOB_BASE + #define USB_DISC_DEV GPIOB #define USB_DISC_PIN 8 #else diff --git a/libmaple/usb/usb_hardware.c b/libmaple/usb/usb_hardware.c index 505dcf1..9a7d12c 100644 --- a/libmaple/usb/usb_hardware.c +++ b/libmaple/usb/usb_hardware.c @@ -33,47 +33,6 @@ #include "usb_hardware.h" -void setPin(u32 bank, u8 pin) { - u32 pinMask = 0x1 << (pin); - SET_REG(GPIO_BSRR(bank),pinMask); -} - -void resetPin(u32 bank, u8 pin) { - u32 pinMask = 0x1 << (16+pin); - SET_REG(GPIO_BSRR(bank),pinMask); -} - -void systemReset(void) { - SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x00000001); - SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xF8FF0000); - SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFEF6FFFF); - SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFFFBFFFF); - SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xFF80FFFF); - - SET_REG(RCC_CIR, 0x00000000); // disable all RCC interrupts -} - -void setupCLK (void) { - /* enable HSE */ - SET_REG(RCC_CR,GET_REG(RCC_CR) | 0x00010001); - /* for it to come on */ - while ((GET_REG(RCC_CR) & 0x00020000) == 0); - - /* Configure PLL */ - /* pll=72Mhz,APB1=36Mhz,AHB=72Mhz */ - SET_REG(RCC_CFGR,GET_REG(RCC_CFGR) | 0x001D0400); - /* enable the pll */ - SET_REG(RCC_CR,GET_REG(RCC_CR) | 0x01000000); - /* wait for it to come on */ - while ((GET_REG(RCC_CR) & 0x03000000) == 0); - - /* Set SYSCLK as PLL */ - SET_REG(RCC_CFGR,GET_REG(RCC_CFGR) | 0x00000002); - /* wait for it to come on */ - while ((GET_REG(RCC_CFGR) & 0x00000008) == 0); -} - - void nvicInit(NVIC_InitTypeDef* NVIC_InitStruct) { u32 tmppriority = 0x00; u32 tmpreg = 0x00; diff --git a/libmaple/usb/usb_hardware.h b/libmaple/usb/usb_hardware.h index e4a26b4..cfead1a 100644 --- a/libmaple/usb/usb_hardware.h +++ b/libmaple/usb/usb_hardware.h @@ -22,34 +22,20 @@ * THE SOFTWARE. * ****************************************************************************/ -#ifndef __HARDWARE_H -#define __HARDWARE_H - +#include "rcc.h" #include "usb_type.h" +#ifndef _USB_HARDWARE_H_ +#define _USB_HARDWARE_H_ + /* macro'd register and peripheral definitions */ #define EXC_RETURN 0xFFFFFFF9 #define DEFAULT_CPSR 0x61000000 -#define RCC ((u32)0x40021000) #define FLASH ((u32)0x40022000) -#define GPIOA ((u32)0x40010800) -#define GPIOC ((u32)0x40011000) #define USB_PACKET_BUFFER ((u32)0x40006000) -#define RCC_CR RCC -#define RCC_CFGR RCC + 0x04 -#define RCC_CIR RCC + 0x08 -#define RCC_AHBENR RCC + 0x14 -#define RCC_APB2ENR RCC + 0x18 -#define RCC_APB1ENR RCC + 0x16 - -#define GPIO_CRL(port) port -#define GPIO_CRH(port) port+0x04 -#define GPIO_ODR(port) port+0x0c -#define GPIO_BSRR(port) port+0x10 - #define SCS_BASE ((u32)0xE000E000) #define NVIC_BASE (SCS_BASE + 0x0100) #define SCB_BASE (SCS_BASE + 0x0D00) @@ -74,9 +60,8 @@ #define __PSC(__TIMCLK, __PERIOD) (((__VAL(__TIMCLK, __PERIOD)+49999UL)/50000UL) - 1) #define __ARR(__TIMCLK, __PERIOD) ((__VAL(__TIMCLK, __PERIOD)/(__PSC(__TIMCLK, __PERIOD)+1)) - 1) -/* todo, wrap in do whiles for the natural ; */ -#define SET_REG(addr,val) *(vu32*)(addr)=val -#define GET_REG(addr) *(vu32*)(addr) +#define SET_REG(addr,val) do { *(vu32*)(addr)=val; } while (0) +#define GET_REG(addr) do { *(vu32*)(addr); } while (0) #if defined(__cplusplus) extern "C" { @@ -85,7 +70,7 @@ extern "C" { /* todo: there must be some major misunderstanding in how we access regs. The direct access approach (GET_REG) causes the usb init to fail upon trying to activate RCC_APB1 |= 0x00800000. However, using the struct approach from ST, it works fine...temporarily switching to that approach */ -typedef struct +typedef struct { vu32 CR; vu32 CFGR; @@ -98,7 +83,7 @@ typedef struct vu32 BDCR; vu32 CSR; } RCC_RegStruct; -#define pRCC ((RCC_RegStruct *) RCC) +#define pRCC ((RCC_RegStruct *) RCC_BASE) typedef struct { vu32 ISER[2]; @@ -139,12 +124,7 @@ typedef struct { } SCB_TypeDef; -void setPin (u32 bank, u8 pin); -void resetPin (u32 bank, u8 pin); - void systemHardReset(void); -void systemReset (void); -void setupCLK (void); void nvicInit (NVIC_InitTypeDef*); void nvicDisableInterrupts(void); diff --git a/libmaple/util.c b/libmaple/util.c index 3408a2e..09fbecd 100644 --- a/libmaple/util.c +++ b/libmaple/util.c @@ -38,7 +38,7 @@ #ifndef ERROR_USART_NUM #define ERROR_USART_NUM USART2 #define ERROR_USART_BAUD 9600 -#define ERROR_TX_PORT GPIOA_BASE +#define ERROR_TX_PORT GPIOA #define ERROR_TX_PIN 2 #endif @@ -87,7 +87,7 @@ void __error(void) { */ 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); + gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_AF_OUTPUT_PP); usart_init(ERROR_USART_NUM, ERROR_USART_BAUD); /* Print failed assert message */ @@ -116,7 +116,7 @@ void throb(void) { uint32 TOP_CNT = 0x0200; uint32 i = 0; - gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); + gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_OUTPUT_PP); /* Error fade */ while (1) { if (CC == TOP_CNT) { diff --git a/libmaple/util.h b/libmaple/util.h index fb524c2..25dd56e 100644 --- a/libmaple/util.h +++ b/libmaple/util.h @@ -28,6 +28,8 @@ * @brief Various macros and utility procedures. */ +#include "libmaple_types.h" + /* Generally "useful" utility procedures */ #ifndef _UTIL_H_ #define _UTIL_H_ @@ -51,40 +53,29 @@ extern "C"{ /* Return bits m to n of x */ #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 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)) -#define REG_CLEAR_BIT(reg, bit) (*(volatile uint32*)(reg) &= ~BIT(bit)) -#define REG_SET_MASK(reg, mask) (*(volatile uint32*)(reg) |= (uint32)(mask)) -#define REG_CLEAR_MASK(reg, mask) (*(volatile uint32*)(reg) &= (uint32)~(mask)) - -#define REG_GET(reg) (*(volatile uint32*)(reg)) +/* + * Register reads and writes + */ #define __set_bits(addr, mask) (*(volatile uint32*)(addr) |= (uint32)(mask)) #define __clear_bits(addr, mask) (*(volatile uint32*)(addr) &= (uint32)~(mask)) #define __get_bits(addr, mask) (*(volatile uint32*)(addr) & (uint32)(mask)) - #define __read(reg) (*(volatile uint32*)(reg)) #define __write(reg, value) (*(volatile uint32*)(reg) = (value)) #define IS_POWER_OF_TWO(v) (v && !(v & (v - 1))) + +/* + * Failure routines + */ + void __error(void); void _fail(const char*, int, const char*); void throb(void); -/* Asserts for sanity checks, redefine DEBUG_LEVEL in libmaple.h to - * compile out these checks */ +/* + * Asserts and debug levels + */ #if DEBUG_LEVEL >= DEBUG_ALL #define ASSERT(exp) \ diff --git a/notes/coding_standard.txt b/notes/coding_standard.txt index 5cb96c3..372ebf4 100644 --- a/notes/coding_standard.txt +++ b/notes/coding_standard.txt @@ -25,12 +25,11 @@ License ------- - Put an MIT license at the beginning of the file (look at any of our - source files for an example). Copyright should go to either you or - LeafLabs LLC. + source files for an example). Copyright should go either to you or + to LeafLabs, LLC. Emacs: if you don't like seeing the license, you should use - elide-head (which will hide it for you). Here is some elisp you can - modify to make this pleasant: + elide-head (which will hide it for you). You can use the following: (require 'elide-head) (setq programming-mode-hooks '(c-mode-hook c++-mode-hook)) @@ -38,7 +37,7 @@ License '("The MIT License" . "DEALINGS IN\n [*] THE SOFTWARE")) (add-to-list 'elide-head-headers-to-hide '("The MIT License" . "DEALINGS IN THE\n...SOFTWARE")) - (dolist (hook mbolivar-programming-mode-hooks) + (dolist (hook programming-mode-hooks) (add-hook hook (lambda () (elide-head)))) Whitespace/Indentation @@ -46,7 +45,8 @@ Whitespace/Indentation - 4 space indents. [Set in .dir-locals.el] -- Unix newlines. +- Unix newlines. [Some exceptions are currently grandfathered in; + these will go away in time.] - No tab characters. [Set in .dir-locals.el] @@ -76,50 +76,53 @@ Whitespace/Indentation (add-hook 'c-mode-hook c-mode-inextern-lang-hook) - Comments -------- -- Multi-line comments look like this: +- Multi-line comments are pretty flexible. Any of these is fine: - /* text starts here - * continued lines have a '*' before them - * the comment can end after the last line + /* Comment starts here. + * Continued lines have a '*' before them. + * The comment can end after the last line. */ - or this: - - /* comment starts here - * the comment can end on the same line */ + /* Comment starts here. + * The comment can end on the same line. */ -- Doxygen comments are newline comments that begin with /** instead. - It is not required that the "/**" appear on a line by itself. + /* + * You can also place a newline after the opening "/*". + */ -- Single-line comments on the same line are // in c or c++. +- Doxygen comments are multi-line comments that begin with /** instead. -- Single-line comments on their own source line are /* */ in c, but - can also be // in c++. If you think that typing out /* */ is too - slow in emacs, use M-; (comment-dwim) when you're on an empty line, - and it'll ... well... +- Single-line comments on the same line are // in C or C++. - You should be using the (super awesome) comment-dwim; it pretty - much does exactly what you want to the comment on the current - line, including "create one and put it in the right place". +- Single-line comments on their own source line should be /* */ in C, + but can also be // in C++. In Emacs, you can use M-; + (comment-dwim), and it'll Do What You Mean. Braces ------ -- 1TBS. Nothing more need be said. +- Mostly 1TBS: http://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS + The only difference is that the opening brace of a function's + definition occurs exactly one space character after the closing + parenthesis in that function's parameter list. Example: + + void func(void) { + ... + } + Naming conventions ------------------ -- There's always a fight about upper and lower case vs. underscores. - We'll handle this as follows. +There's always a fight about upper and lower case vs. underscores. +We'll handle this as follows. - First, Dammit_Dont_Mix_Like_This, because It_Looks_Really_Ugly, ok? +- First, Dammit_Dont_Mix_Like_This, because It_Looks_Really_Ugly, ok? [There's been some debate about this, and some exceptions are already grandfathered in, so in order to settle it, let's call this a "recommendation" instead of "requirement".] @@ -168,7 +171,7 @@ Naming conventions Documentation ------------- -- Document your code. This should go without saying. +- Document your code! - For complicated peripherals, it would be nice if you put longer-form comments into this directory (notes/), with a comment in the @@ -176,13 +179,8 @@ Documentation example. That lets us keep the source files relatively clean while still allowing new readers to have a starting point. -- At least put a doxygen comment with a nonempty @brief for every .h - file you add. See the existing ones for examples. For now, it'd be - better if you didn't put a @brief into any .c[pp] files, since it - (currently) interferes with our documentation generator in a way - that I won't explain here (though you can look into the LeafLabs or - michaeljones breathe repos on github and potentially figure out - why). +- At least put a Doxygen comment with a nonempty @brief for every .h + file you add. See the existing ones for examples. - Doxygen comments generally just belong on types, functions, etc. that are part of the public user-facing API. This generally @@ -196,8 +194,13 @@ Documentation This should be avoided if at all possible, since it creates a maintenance burden of documenting things in two places at once, and - provides an opportunity for bad documentation to slip in, when the - code comments fall out of sync with the ReST docs. + makes it easier for documentation to go stale. + +- For libmaple proper (the pure C library under libmaple/); the + convention is to document any user-facing entity at the point where + it is defined. In particular, this means you should document an + externally-linked function defined in a .c file in that .c file, not + in the header file where it is declared to the user. General Formatting ------------------ @@ -217,7 +220,3 @@ General Formatting (require 'lineker) (dolist (hook '(c-mode-hook c++-mode-hook)) (add-hook hook (lambda () (lineker-mode 1)))) - - There are only a few exceptional situations. The most important one - is when specifying a lookup table like PIN_MAP where it'd be ugly to - split each entry over multiple lines. diff --git a/notes/exti.txt b/notes/exti.txt new file mode 100644 index 0000000..1ad49ee --- /dev/null +++ b/notes/exti.txt @@ -0,0 +1,67 @@ +External interrupt notes. + +To generate the interrupt, the interrupt line should be configured +and enabled. This is done by programming the two trigger registers +with the desired edge detection and by enabling the interrupt +request by writing a '1' to the corresponding bit in the interrupt +mask register. When the selected edge occurs on the external +interrupt line, an interrupt request is generated. The pending bit +corresponding to the interrupt line is also set. This request is +reset by writing a '1' in the pending register. + +Hardware interrupt selection: + +To configure the 20 lines as interrupt sources, use the following +procedure: + +1) Configure AFIO_EXTICR[y] to select the source input for EXTIx + external interrupt +2) Configure the mask bits of the 20 interrupt lines (EXTI_IMR) +3) Configure the trigger selection bits of the interrupt lines + (EXTI_RTSR and EXTI_FTSR) +4) Configure the enable and mask bits that control the NVIC_IRQ + channel mapped to the External Interrupt Controller (EXTI) so + that an inerrupt coming from one of the 20 lines can be + correctly acknowledged. + +AFIO clock must be on. + +RM0008, page 107: "PD0, PD1 cannot be used for external +interrupt/event generation on 36, 48, 64-bin packages." + +---------------------------------------------------------------------------- +Pin to EXTI Line Mappings: +EXTI0 EXTI1 EXTI2 EXTI3 EXTI4 +-------------------------------------------------------------------------- +D2/PA0 D3/PA1 D1/PA2 D0/A6/PA3 D10/A10/PA4 +D26/EXT7/PB0 D27/EXT8/PB1 D16/A2/PC2 D17/A3/PC3 D18/A4/PC4 +D14/A0/PC0 D15/PC1 D25/EXT5/PD2 + +EXTI5 EXTI6 EXTI7 EXTI8 EXTI9 +---------------------------------------------------------------------------- +D13/A13/PA5 D12/A12/PA6 D11/A11/PA7 D6/PA8 D7/PA9 +D4/PB5 D5/PB6 D9/PB7 D38/PB8 D23/EXT4/PB9 +D19/A5/PC5 D34/EXTI15/PC6 D35/EXT16/PC7 D36/PC8 D37/EXT18/PC9 + +EXTI10 EXTI11 EXTI12 EXTI13 EXTI14 +---------------------------------------------------------------------------- +D8/PA10 D29/EXT10/PB11 D30/EXTI1/PB12 D31/EXTI12/PB13 D32/EXT13/PB14 +D28/PB10 D20/EXTI1/PC13 D21/EXT2/PC14 +D25/PC10 + +EXTI15 +---------------------------------------------------------------------------- +D33/EXTI14/PB15 +D22/EXT3/PC15 + + +The 16 EXTI interrupts are mapped to 7 interrupt handlers. + +EXTI Lines to Interrupt Mapping: +EXTI0 -> EXTI0 +EXTI1 -> EXTI1 +EXTI2 -> EXTI2 +EXTI3 -> EXTI3 +EXTI4 -> EXTI4 +EXTI[5-9] -> EXT9_5 +EXTI[10-15] -> EXT15_10 diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp index 0f8bec6..04d1c76 100644 --- a/wirish/HardwareTimer.cpp +++ b/wirish/HardwareTimer.cpp @@ -89,7 +89,7 @@ uint16 HardwareTimer::setPeriod(uint32 microseconds) { return this->getOverflow(); } -inline void HardwareTimer::setChannelMode(int channel, TimerMode mode) { +void HardwareTimer::setChannelMode(int channel, TimerMode mode) { timer_set_mode(this->timerNum, channel, mode); } @@ -109,7 +109,7 @@ void HardwareTimer::setChannel4Mode(TimerMode mode) { this->setChannelMode(4, mode); } -inline uint16 HardwareTimer::getCompare(int channel) { +uint16 HardwareTimer::getCompare(int channel) { return timer_get_compare_value(this->timerNum, channel); } @@ -129,7 +129,7 @@ uint16 HardwareTimer::getCompare4() { return this->getCompare(4); } -inline void HardwareTimer::setCompare(int channel, uint16 val) { +void HardwareTimer::setCompare(int channel, uint16 val) { uint16 ovf = this->getOverflow(); timer_set_compare_value(this->timerNum, channel, min(val, ovf)); } @@ -150,7 +150,7 @@ void HardwareTimer::setCompare4(uint16 val) { this->setCompare(4, val); } -inline void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) { +void HardwareTimer::attachInterrupt(int channel, voidFuncPtr handler) { timer_attach_interrupt(this->timerNum, channel, handler); } @@ -170,7 +170,7 @@ void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler) { this->attachInterrupt(4, handler); } -inline void HardwareTimer::detachInterrupt(int channel) { +void HardwareTimer::detachInterrupt(int channel) { timer_detach_interrupt(this->timerNum, channel); } @@ -194,7 +194,6 @@ void HardwareTimer::generateUpdate(void) { timer_generate_update(this->timerNum); } - HardwareTimer Timer1(TIMER1); HardwareTimer Timer2(TIMER2); HardwareTimer Timer3(TIMER3); diff --git a/wirish/boards.cpp b/wirish/boards.cpp new file mode 100644 index 0000000..9276f36 --- /dev/null +++ b/wirish/boards.cpp @@ -0,0 +1,387 @@ +#include "boards.h" + +// think of the poor column numbers +#define ADCx ADC_INVALID +#define TIMERx TIMER_INVALID + +#if defined(BOARD_maple) + +PinMapping PIN_MAP[NR_GPIO_PINS] = { + /* D0/PA3 */ + {GPIOA, 3, 3, TIMER2_CH4_CCR, TIMER2, 4, AFIO_EXTI_PA}, + /* D1/PA2 */ + {GPIOA, 2, 2, TIMER2_CH3_CCR, TIMER2, 3, AFIO_EXTI_PA}, + /* D2/PA0 */ + {GPIOA, 0, 0, TIMER2_CH1_CCR, TIMER2, 1, AFIO_EXTI_PA}, + /* D3/PA1 */ + {GPIOA, 1, 1, TIMER2_CH2_CCR, TIMER2, 2, AFIO_EXTI_PA}, + /* D4/PB5 */ + {GPIOB, 5, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D5/PB6 */ + {GPIOB, 6, ADCx, TIMER4_CH1_CCR, TIMER4, 1, AFIO_EXTI_PB}, + /* D6/PA8 */ + {GPIOA, 8, ADCx, TIMER1_CH1_CCR, TIMER1, 1, AFIO_EXTI_PA}, + /* D7/PA9 */ + {GPIOA, 9, ADCx, TIMER1_CH2_CCR, TIMER1, 2, AFIO_EXTI_PA}, + /* D8/PA10 */ + {GPIOA, 10, ADCx, TIMER1_CH3_CCR, TIMER1, 3, AFIO_EXTI_PA}, + /* D9/PB7 */ + {GPIOB, 7, ADCx, TIMER4_CH2_CCR, TIMER4, 2, AFIO_EXTI_PB}, + /* D10/PA4 */ + {GPIOA, 4, 4, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D11/PA7 */ + {GPIOA, 7, 7, TIMER3_CH2_CCR, TIMER3, 2, AFIO_EXTI_PA}, + /* D12/PA6 */ + {GPIOA, 6, 6, TIMER3_CH1_CCR, TIMER3, 1, AFIO_EXTI_PA}, + /* D13/PA5 */ + {GPIOA, 5, 5, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D14/PB8 */ + {GPIOB, 8, ADCx, TIMER4_CH3_CCR, TIMER4, 3, AFIO_EXTI_PB}, + + /* Little header */ + + /* D15/PC0 */ + {GPIOC, 0, 10, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D16/PC1 */ + {GPIOC, 1, 11, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D17/PC2 */ + {GPIOC, 2, 12, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D18/PC3 */ + {GPIOC, 3, 13, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D19/PC4 */ + {GPIOC, 4, 14, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D20/PC5 */ + {GPIOC, 5, 15, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + + /* External header */ + + /* D21/PC13 */ + {GPIOC, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D22/PC14 */ + {GPIOC, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D23/PC15 */ + {GPIOC, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D24/PB9 */ + {GPIOB, 9, ADCx, TIMER4_CH4_CCR, TIMER4, 4, AFIO_EXTI_PB}, + /* D25/PD2 */ + {GPIOD, 2, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D26/PC10 */ + {GPIOC, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D27/PB0 */ + {GPIOB, 0, 8, TIMER3_CH3_CCR, TIMER3, 3, AFIO_EXTI_PB}, + /* D28/PB1 */ + {GPIOB, 1, 9, TIMER3_CH4_CCR, TIMER3, 4, AFIO_EXTI_PB}, + /* D29/PB10 */ + {GPIOB, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D30/PB11 */ + {GPIOB, 11, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D31/PB12 */ + {GPIOB, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D32/PB13 */ + {GPIOB, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D33/PB14 */ + {GPIOB, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D34/PB15 */ + {GPIOB, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D35/PC6 */ + {GPIOC, 6, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D36/PC7 */ + {GPIOC, 7, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D37/PC8 */ + {GPIOC, 8, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D38/PC9 (BUT) */ + {GPIOC, 9, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC} +}; + +#elif defined(BOARD_maple_native) + +PinMapping PIN_MAP[NR_GPIO_PINS] = { + /* Top header */ + + /* D0/PB10 */ + {GPIOB, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D1/PB2 */ + {GPIOB, 2, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D2/PB12 */ + {GPIOB, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D3/PB13 */ + {GPIOB, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D4/PB14 */ + {GPIOB, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D5/PB15 */ + {GPIOB, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D6/PC0 */ + {GPIOC, 0, 10, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D7/PC1 */ + {GPIOC, 1, 11, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D8/PC2 */ + {GPIOC, 2, 12, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D9/PC3 */ + {GPIOC, 3, 13, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D10/PC4 */ + {GPIOC, 4, 14, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D11/PC5 */ + {GPIOC, 5, 15, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D12/PC6 */ + {GPIOC, 6, ADCx, TIMER8_CH1_CCR, TIMER8, 1, AFIO_EXTI_PC}, + /* D13/PC7 */ + {GPIOC, 7, ADCx, TIMER8_CH2_CCR, TIMER8, 2, AFIO_EXTI_PC}, + /* D14/PC8 */ + {GPIOC, 8, ADCx, TIMER8_CH3_CCR, TIMER8, 3, AFIO_EXTI_PC}, + /* D15/PC9 */ + {GPIOC, 9, ADCx, TIMER8_CH4_CCR, TIMER8, 4, AFIO_EXTI_PC}, + /* D16/PC10 */ + {GPIOC, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D17/PC11 */ + {GPIOC, 11, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D18/PC12 */ + {GPIOC, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D19/PC13 */ + {GPIOC, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D20/PC14 */ + {GPIOC, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D21/PC15 */ + {GPIOC, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D22/PA8 */ + {GPIOA, 8, ADCx, TIMER1_CH1_CCR, TIMER1, 1, AFIO_EXTI_PA}, + /* D23/PA9 */ + {GPIOA, 9, ADCx, TIMER1_CH2_CCR, TIMER1, 2, AFIO_EXTI_PA}, + /* D24/PA10 */ + {GPIOA, 10, ADCx, TIMER1_CH3_CCR, TIMER1, 3, AFIO_EXTI_PA}, + /* D25/PB9 */ + {GPIOB, 9, ADCx, TIMER4_CH4_CCR, TIMER4, 4, AFIO_EXTI_PB}, + + /* Bottom header */ + + /* D26/PD2 */ + {GPIOD, 2, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D27/PD3 */ + {GPIOD, 3, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D28/PD6 */ + {GPIOD, 6, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D29/PG11 */ + {GPIOG, 11, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D30/PG12 */ + {GPIOG, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D31/PG13 */ + {GPIOG, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D32/PG14 */ + {GPIOG, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D33/PG8 */ + {GPIOG, 8, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D34/PG7 */ + {GPIOG, 7, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D35/PG6 */ + {GPIOG, 6, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D36/PB5 */ + {GPIOB, 5, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D37/PB6 */ + {GPIOB, 6, ADCx, TIMER4_CH1_CCR, TIMER4, 1, AFIO_EXTI_PB}, + /* D38/PB7 */ + {GPIOB, 7, ADCx, TIMER4_CH2_CCR, TIMER4, 2, AFIO_EXTI_PB}, + /* D39/PF6 */ + {GPIOF, 6, 4, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D40/PF7 */ + {GPIOF, 7, 5, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D41/PF8 */ + {GPIOF, 8, 6, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D42/PF9 */ + {GPIOF, 9, 7, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D43/PF10 */ + {GPIOF, 10, 8, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D44/PF11 */ + {GPIOF, 11, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D45/PB1 */ + {GPIOB, 1, 9, TIMER3_CH4_CCR, TIMER3, 4, AFIO_EXTI_PB}, + /* D46/PB0 */ + {GPIOB, 0, 8, TIMER3_CH3_CCR, TIMER3, 3, AFIO_EXTI_PB}, + /* D47/PA0 */ + {GPIOA, 0, 0, TIMER5_CH1_CCR, TIMER5, 1, AFIO_EXTI_PA}, + /* D48/PA1 */ /* FIXME (?) + What about D48--D50 also being TIMER2_CH[234]? */ + {GPIOA, 1, 1, TIMER5_CH2_CCR, TIMER5, 2, AFIO_EXTI_PA}, + /* D49/PA2 */ + {GPIOA, 2, 2, TIMER5_CH3_CCR, TIMER5, 3, AFIO_EXTI_PA}, + /* D50/PA3 */ + {GPIOA, 3, 3, TIMER5_CH4_CCR, TIMER5, 4, AFIO_EXTI_PA}, + /* D51/PA4 */ + {GPIOA, 4, 4, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D52/PA5 */ + {GPIOA, 5, 5, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D53/PA6 */ + {GPIOA, 6, 6, TIMER3_CH1_CCR, TIMER3, 1, AFIO_EXTI_PA}, + /* D54/PA7 */ + {GPIOA, 7, 7, TIMER3_CH2_CCR, TIMER3, 2, AFIO_EXTI_PA}, + + /* Right (triple) header */ + + /* D55/PF0 */ + {GPIOF, 0, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D56/PD11 */ + {GPIOD, 11, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D57/PD14 */ + {GPIOD, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D58/PF1 */ + {GPIOF, 1, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D59/PD12 */ + {GPIOD, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D60/PD15 */ + {GPIOD, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D61/PF2 */ + {GPIOF, 2, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D62/PD13 */ + {GPIOD, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D63/PD0 */ + {GPIOD, 0, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D64/PF3 */ + {GPIOF, 3, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D65/PE3 */ + {GPIOE, 3, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D66/PD1 */ + {GPIOD, 1, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D67/PF4 */ + {GPIOF, 4, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D68/PE4 */ + {GPIOE, 4, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D69/PE7 */ + {GPIOE, 7, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D70/PF5 */ + {GPIOF, 5, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D71/PE5 */ + {GPIOE, 5, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D72/PE8 */ + {GPIOE, 8, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D73/PF12 */ + {GPIOF, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D74/PE6 */ + {GPIOE, 6, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D75/PE9 */ + {GPIOE, 9, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D76/PF13 */ + {GPIOF, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D77/PE10 */ + {GPIOE, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D78/PF14 */ + {GPIOF, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D79/PG9 */ + {GPIOG, 9, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D80/PE11 */ + {GPIOE, 11, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D81/PF15 */ + {GPIOF, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PF}, + /* D82/PG10 */ + {GPIOG, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D83/PE12 */ + {GPIOE, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D84/PG0 */ + {GPIOG, 0, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D85/PD5 */ + {GPIOD, 5, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D86/PE13 */ + {GPIOE, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D87/PG1 */ + {GPIOG, 1, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D88/PD4 */ + {GPIOD, 4, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D89/PE14 */ + {GPIOE, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D90/PG2 */ + {GPIOG, 2, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D91/PE1 */ + {GPIOE, 1, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D92/PE15 */ + {GPIOE, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D93/PG3 */ + {GPIOG, 3, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D94/PE0 */ + {GPIOE, 0, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PE}, + /* D95/PD8 */ + {GPIOD, 8, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D96/PG4 */ + {GPIOG, 4, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D97/PD9 */ + {GPIOD, 9, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D98/PG5 */ + {GPIOG, 5, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PG}, + /* D99/PD10 */ + {GPIOD, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PDD} +}; + +#elif defined(BOARD_maple_mini) + +PinMapping PIN_MAP[NR_GPIO_PINS] = { + /* D0/PB11 */ + {GPIOB, 11, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D1/PB10 */ + {GPIOB, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D2/PB2 */ + {GPIOB, 2, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D3/PB0 */ + {GPIOB, 0, 8, TIMER3_CH3_CCR, TIMER3, 3, AFIO_EXTI_PB}, + /* D4/PA7 */ + {GPIOA, 7, 7, TIMER3_CH2_CCR, TIMER3, 2, AFIO_EXTI_PA}, + /* D5/PA6 */ + {GPIOA, 6, 6, TIMER3_CH1_CCR, TIMER3, 1, AFIO_EXTI_PA}, + /* D6/PA5 */ + {GPIOA, 5, 5, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D7/PA4 */ + {GPIOA, 4, 4, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D8/PA3 */ + {GPIOA, 3, 3, TIMER2_CH4_CCR, TIMER2, 4, AFIO_EXTI_PA}, + /* D9/PA2 */ + {GPIOA, 2, 2, TIMER2_CH3_CCR, TIMER2, 3, AFIO_EXTI_PA}, + /* D10/PA1 */ + {GPIOA, 1, 1, TIMER2_CH2_CCR, TIMER2, 2, AFIO_EXTI_PA}, + /* D11/PA0 */ + {GPIOA, 0, 0, TIMER2_CH1_CCR, TIMER2, 1, AFIO_EXTI_PA}, + /* D12/PC15 */ + {GPIOC, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D13/PC14 */ + {GPIOC, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D14/PC13 */ + {GPIOC, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D15/PB7 */ + {GPIOB, 7, ADCx, TIMER4_CH2_CCR, TIMER4, 2, AFIO_EXTI_PB}, + /* D16/PB6 */ + {GPIOB, 6, ADCx, TIMER4_CH1_CCR, TIMER4, 1, AFIO_EXTI_PB}, + /* D17/PB5 */ + {GPIOB, 5, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D18/PB4 */ + {GPIOB, 4, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D19/PB3 */ + {GPIOB, 3, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D20/PA15 */ + {GPIOA, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D21/PA14 */ + {GPIOA, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D22/PA13 */ + {GPIOA, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D23/PA12 */ + {GPIOA, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D24/PA11 */ + {GPIOA, 11, ADCx, TIMER1_CH4_CCR, TIMER1, 4, AFIO_EXTI_PA}, + /* D25/PA10 */ + {GPIOA, 10, ADCx, TIMER1_CH3_CCR, TIMER1, 3, AFIO_EXTI_PA}, + /* D26/PA9 */ + {GPIOA, 9, ADCx, TIMER1_CH2_CCR, TIMER2, 2, AFIO_EXTI_PA}, + /* D27/PA8 */ + {GPIOA, 8, ADCx, TIMER1_CH1_CCR, TIMER1, 1, AFIO_EXTI_PA}, + /* D28/PB15 */ + {GPIOB, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D29/PB14 */ + {GPIOB, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D30/PB13 */ + {GPIOB, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D31/PB12 */ + {GPIOB, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D32/PB8 */ + {GPIOB, 8, ADCx, TIMER4_CH3_CCR, TIMER4, 3, AFIO_EXTI_PB}, + /* D33/PB1 */ + {GPIOB, 1, 9, TIMER3_CH4_CCR, TIMER3, 4, AFIO_EXTI_PB}, +}; + +#else + +#error "Board type has not been selected correctly." + +#endif diff --git a/wirish/boards.h b/wirish/boards.h index ee93c5a..2941127 100644 --- a/wirish/boards.h +++ b/wirish/boards.h @@ -34,13 +34,11 @@ #include "libmaple.h" #include "gpio.h" #include "timers.h" -#include "exti.h" -#ifdef __cplusplus -extern "C" { -#endif - -/* Set of all possible digital pin names; not all boards have all these */ +/* Set of all possible pin names; not all boards have all these (note + that we use the Dx convention since all of the Maple's pins are + "digital" pins (e.g. can be used with digitalRead() and + digitalWrite()), but not all of them are connected to ADCs. */ enum { D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, @@ -53,17 +51,20 @@ enum { #define ADC_INVALID 0xFFFFFFFF -/* Types used for the tables below */ +/* Pin mapping: pin number -> STM32 info */ typedef struct PinMapping { - GPIO_Port *port; + gpio_dev *gpio_device; uint32 pin; uint32 adc_channel; TimerCCR timer_ccr; - uint32 exti_port; timer_dev_num timer_num; uint32 timer_chan; + afio_exti_port ext_port; } PinMapping; +/* Maps every digital pin to a PinMapping */ +extern PinMapping PIN_MAP[]; + /* LeafLabs Maple rev3, rev5 */ #ifdef BOARD_maple @@ -77,93 +78,6 @@ typedef struct PinMapping { intended for general use. */ #define NR_GPIO_PINS 39 - static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { - /* D0/PA3 */ - {GPIOA_BASE, 3, 3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, - /* D1/PA2 */ - {GPIOA_BASE, 2, 2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, - /* D2/PA0 */ - {GPIOA_BASE, 0, 0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1}, - /* D3/PA1 */ - {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}, - /* D5/PB6 */ - {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}, - /* D7/PA9 */ - {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}, - /* D9/PB7 */ - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2}, - /* D10/PA4 */ - {GPIOA_BASE, 4, 4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D11/PA7 */ - {GPIOA_BASE, 7, 7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, - /* D12/PA6 */ - {GPIOA_BASE, 6, 6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, - /* D13/PA5 */ - {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}, - - /* Little header */ - - /* D15/PC0 */ - {GPIOC_BASE, 0, 10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D16/PC1 */ - {GPIOC_BASE, 1, 11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D17/PC2 */ - {GPIOC_BASE, 2, 12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D18/PC3 */ - {GPIOC_BASE, 3, 13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D19/PC4 */ - {GPIOC_BASE, 4, 14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D20/PC5 */ - {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}, - /* D22/PC14 */ - {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}, - /* D24/PB9 */ - {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER4, 4}, - /* D25/PD2 */ - {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}, - /* D27/PB0 */ - {GPIOB_BASE, 0, 8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, - /* D28/PB1 */ - {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}, - /* D30/PB11 */ - {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}, - /* D32/PB13 */ - {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}, - /* D34/PB15 */ - {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}, - /* D36/PC7 */ - {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}, - /* D38/PC9 (BUT) */ - {GPIOC_BASE, 9, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID} - }; - #define BOARD_INIT do { \ } while(0) @@ -179,218 +93,6 @@ typedef struct PinMapping { #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}, - /* D1/PB2 */ - {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}, - /* D3/PB13 */ - {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}, - /* D5/PB15 */ - {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D6/PC0 */ - {GPIOC_BASE, 0, 10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D7/PC1 */ - {GPIOC_BASE, 1, 11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D8/PC2 */ - {GPIOC_BASE, 2, 12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D9/PC3 */ - {GPIOC_BASE, 3, 13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D10/PC4 */ - {GPIOC_BASE, 4, 14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D11/PC5 */ - {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}, - /* D13/PC7 */ - {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}, - /* D15/PC9 */ - {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}, - /* D17/PC11 */ - {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}, - /* D19/PC13 */ - {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}, - /* D21/PC15 */ - {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}, - /* D23/PA9 */ - {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}, - /* D25/PB9 */ - {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}, - /* D27/PD3 */ - {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}, - /* D29/PG11 */ - {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}, - /* D31/PG13 */ - {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}, - /* D33/PG8 */ - {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}, - /* D35/PG6 */ - {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}, - /* D37/PB6 */ - {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}, - /* D39/PF6 */ - {GPIOF_BASE, 6, 4, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, - /* D40/PF7 */ - {GPIOF_BASE, 7, 5, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, - /* D41/PF8 */ - {GPIOF_BASE, 8, 6, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, - /* D42/PF9 */ - {GPIOF_BASE, 9, 7, 0, EXTI_CONFIG_PORTF, TIMER_INVALID, TIMER_INVALID}, - /* D43/PF10 */ - {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}, - /* D45/PB1 */ - {GPIOB_BASE, 1, 9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, - /* D46/PB0 */ - {GPIOB_BASE, 0, 8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, - /* D47/PA0 */ - {GPIOA_BASE, 0, 0, TIMER5_CH1_CCR, EXTI_CONFIG_PORTA, TIMER5, 1}, - /* D48/PA1 */ - {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, 2, TIMER5_CH3_CCR, EXTI_CONFIG_PORTA, TIMER5, 3}, - /* D50/PA3 */ - {GPIOA_BASE, 3, 3, TIMER5_CH4_CCR, EXTI_CONFIG_PORTA, TIMER5, 4}, - /* D51/PA4 */ - {GPIOA_BASE, 4, 4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D52/PA5 */ - {GPIOA_BASE, 5, 5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D53/PA6 */ - {GPIOA_BASE, 6, 6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, - /* D54/PA7 */ - {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}, - /* D56/PD11 */ - {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}, - /* D58/PF1 */ - {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}, - /* D60/PD15 */ - {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}, - /* D62/PD13 */ - {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}, - /* D64/PF3 */ - {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}, - /* D66/PD1 */ - {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}, - /* D68/PE4 */ - {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}, - /* D70/PF5 */ - {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}, - /* D72/PE8 */ - {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}, - /* D74/PE6 */ - {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}, - /* D76/PF13 */ - {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}, - /* D78/PF14 */ - {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}, - /* D80/PE11 */ - {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}, - /* D82/PG10 */ - {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}, - /* D84/PG0 */ - {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}, - /* D86/PE13 */ - {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}, - /* D88/PD4 */ - {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}, - /* D90/PG2 */ - {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}, - /* D92/PE15 */ - {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}, - /* D94/PE0 */ - {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}, - /* D96/PG4 */ - {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}, - /* D98/PG5 */ - {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} - }; - #define BOARD_INIT do { \ } while(0) @@ -404,83 +106,11 @@ typedef struct PinMapping { #define NR_GPIO_PINS 34 - static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { - /* D0/PB11 */ - {GPIOB_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D1/PB10 */ - {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D2/PB2 */ - {GPIOB_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D3/PB0 */ - {GPIOB_BASE, 0, 8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, - /* D4/PA7 */ - {GPIOA_BASE, 7, 7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, - /* D5/PA6 */ - {GPIOA_BASE, 6, 6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, - /* D6/PA5 */ - {GPIOA_BASE, 5, 5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D7/PA4 */ - {GPIOA_BASE, 4, 4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D8/PA3 */ - {GPIOA_BASE, 3, 3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, - /* D9/PA2 */ - {GPIOA_BASE, 2, 2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, - /* D10/PA1 */ - {GPIOA_BASE, 1, 1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, - /* D11/PA0 */ - {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 */ - {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D14/PC13 */ - {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D15/PB7 */ - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, - /* D16/PB6 */ - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, - /* D17/PB5 */ - {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D18/PB4 */ - {GPIOB_BASE, 4, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D19/PB3 */ - {GPIOB_BASE, 3, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D20/PA15 */ - {GPIOA_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D21/PA14 */ - {GPIOA_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D22/PA13 */ - {GPIOA_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D23/PA12 */ - {GPIOA_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D24/PA11 */ - {GPIOA_BASE, 11, ADC_INVALID, TIMER1_CH4_CCR, EXTI_CONFIG_PORTA, TIMER1, 4}, - /* D25/PA10 */ - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, - /* D26/PA9 */ - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, - /* D27/PA8 */ - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTB, TIMER1, 1}, - /* D28/PB15 */ - {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D29/PB14 */ - {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D30/PB13 */ - {GPIOB_BASE, 13, 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}, - /* D32/PB8 */ - {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB, TIMER4, 3}, - /* D33/PB1 */ - {GPIOB_BASE, 1, 9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, - }; - - /* since we want the Serial Wire/JTAG pins as GPIOs, disable both - SW and JTAG debug support */ - /* don't use __clear_bits here! */ + /* Since we want the Serial Wire/JTAG pins as GPIOs, disable both + * SW and JTAG debug support */ #define BOARD_INIT \ do { \ - *AFIO_MAPR = (*AFIO_MAPR | BIT(26)) & ~(BIT(25) | BIT(24)); \ + afio_mapr_swj_config(AFIO_MAPR_SWJ_NO_JTAG_NO_SW); \ } while (0) #else @@ -489,9 +119,4 @@ typedef struct PinMapping { #endif -#ifdef __cplusplus -} // extern "C" -#endif - #endif - diff --git a/wirish/comm/HardwareSerial.cpp b/wirish/comm/HardwareSerial.cpp index d6c7e82..08252d8 100644 --- a/wirish/comm/HardwareSerial.cpp +++ b/wirish/comm/HardwareSerial.cpp @@ -34,21 +34,21 @@ #include "gpio.h" #include "timers.h" -HardwareSerial Serial1(USART1, 4500000UL, GPIOA_BASE, 9,10, TIMER1, 2); -HardwareSerial Serial2(USART2, 2250000UL, GPIOA_BASE, 2, 3, TIMER2, 3); -HardwareSerial Serial3(USART3, 2250000UL, GPIOB_BASE, 10,11, TIMER_INVALID, 0); +HardwareSerial Serial1(USART1, 4500000UL, GPIOA, 9,10, TIMER1, 2); +HardwareSerial Serial2(USART2, 2250000UL, GPIOA, 2, 3, TIMER2, 3); +HardwareSerial Serial3(USART3, 2250000UL, GPIOB, 10,11, TIMER_INVALID, 0); // TODO: High density device ports HardwareSerial::HardwareSerial(uint8 usart_num, uint32 max_baud, - GPIO_Port *gpio_port, + gpio_dev *gpio_device, uint8 tx_pin, uint8 rx_pin, timer_dev_num timer_num, uint8 compare_num) { this->usart_num = usart_num; this->max_baud = max_baud; - this->gpio_port = gpio_port; + this->gpio_device = gpio_device; this->tx_pin = tx_pin; this->rx_pin = rx_pin; this->timer_num = timer_num; @@ -72,8 +72,8 @@ void HardwareSerial::begin(uint32 baud) { return; } - gpio_set_mode(gpio_port, tx_pin, GPIO_MODE_AF_OUTPUT_PP); - gpio_set_mode(gpio_port, rx_pin, GPIO_MODE_INPUT_FLOATING); + gpio_set_mode(gpio_device, tx_pin, GPIO_AF_OUTPUT_PP); + gpio_set_mode(gpio_device, rx_pin, GPIO_INPUT_FLOATING); if (timer_num != TIMER_INVALID) { /* turn off any pwm if there's a conflict on this usart */ diff --git a/wirish/comm/HardwareSerial.h b/wirish/comm/HardwareSerial.h index aad8aa7..ef19a56 100644 --- a/wirish/comm/HardwareSerial.h +++ b/wirish/comm/HardwareSerial.h @@ -46,7 +46,7 @@ class HardwareSerial : public Print { private: uint8 usart_num; uint32 max_baud; - GPIO_Port *gpio_port; + gpio_dev *gpio_device; uint8 tx_pin; uint8 rx_pin; timer_dev_num timer_num; @@ -54,7 +54,7 @@ class HardwareSerial : public Print { public: HardwareSerial(uint8 usart_num, uint32 max_baud, - GPIO_Port *gpio_port, + gpio_dev *gpio_device, uint8 tx_pin, uint8 rx_pin, timer_dev_num timer_num, diff --git a/wirish/ext_interrupts.c b/wirish/ext_interrupts.c deleted file mode 100644 index dd7c1a8..0000000 --- a/wirish/ext_interrupts.c +++ /dev/null @@ -1,79 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *****************************************************************************/ - -/** - * @file ext_interrupts.c - * - * @brief Wiring-like interface for external interrupts - */ - -#include "wirish.h" -#include "exti.h" -#include "ext_interrupts.h" - -/* Attach ISR handler on pin, triggering on the given mode. */ -void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) { - uint8 outMode; - - /* Parameter checking */ - if (pin >= NR_GPIO_PINS) { - return; - } - - if (!handler) { - return; - } - - switch (mode) { - case RISING: - outMode = EXTI_RISING; - break; - case FALLING: - outMode = EXTI_FALLING; - break; - case CHANGE: - outMode = EXTI_RISING_FALLING; - break; - default: - ASSERT(0); - return; - } - - exti_attach_interrupt(PIN_MAP[pin].exti_port, - PIN_MAP[pin].pin, - handler, - mode); - - return; -} - -/* Disable any interrupts */ -void detachInterrupt(uint8 pin) { - if (!(pin < NR_GPIO_PINS)) { - return; - } - - exti_detach_interrupt(PIN_MAP[pin].pin); -} - diff --git a/wirish/ext_interrupts.cpp b/wirish/ext_interrupts.cpp new file mode 100644 index 0000000..5b32b05 --- /dev/null +++ b/wirish/ext_interrupts.cpp @@ -0,0 +1,82 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *****************************************************************************/ + +/** + * @file ext_interrupts.c + * + * @brief Wiring-like interface for external interrupts + */ + +#include "boards.h" +#include "gpio.h" +#include "exti.h" +#include "ext_interrupts.h" + +static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode); + +/** + * @brief Attach an interrupt handler to a pin, triggering on the given mode. + * @param pin Pin to attach an interrupt handler onto. + * @param handler Function to call when the external interrupt is triggered. + * @param mode Trigger mode for the given interrupt. + * @see ExtIntTriggerMode + */ +void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) { + if (pin >= NR_GPIO_PINS || !handler) { + return; + } + + exti_trigger_mode outMode = exti_out_mode(mode); + + exti_attach_interrupt((afio_exti_num)(PIN_MAP[pin].pin), + PIN_MAP[pin].ext_port, + handler, + outMode); +} + +/** + * @brief Disable any external interrupt attached to a pin. + * @param pin Pin number to detach any interrupt from. + */ +void detachInterrupt(uint8 pin) { + if (pin >= NR_GPIO_PINS) { + return; + } + + exti_detach_interrupt((afio_exti_num)(PIN_MAP[pin].pin)); +} + +static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode) { + switch (mode) { + case RISING: + return EXTI_RISING; + case FALLING: + return EXTI_FALLING; + case CHANGE: + return EXTI_RISING_FALLING; + } + // Can't happen + ASSERT(0); + return (exti_trigger_mode)0; +} diff --git a/wirish/ext_interrupts.h b/wirish/ext_interrupts.h index 4e22c71..364bcda 100644 --- a/wirish/ext_interrupts.h +++ b/wirish/ext_interrupts.h @@ -28,7 +28,7 @@ /** * @file ext_interrupts.h * - * @brief External interrupt wiring prototypes and types + * @brief Wiring-like external interrupt prototypes and types. */ #ifndef _EXT_INTERRUPTS_H_ @@ -48,10 +48,6 @@ typedef enum ExtIntTriggerMode_ { changes). */ } ExtIntTriggerMode; -#ifdef __cplusplus -extern "C"{ -#endif - /** * @brief Registers an interrupt handler on a pin. * @@ -104,10 +100,5 @@ static inline void noInterrupts() { nvic_globalirq_disable(); } -#ifdef __cplusplus -} -#endif - - #endif diff --git a/wirish/io.h b/wirish/io.h index 2d22dcd..d2e4d2d 100644 --- a/wirish/io.h +++ b/wirish/io.h @@ -35,10 +35,6 @@ #include "adc.h" #include "time.h" -#ifdef __cplusplus -extern "C"{ -#endif - /** * Specifies a GPIO pin behavior. * @@ -68,11 +64,11 @@ typedef enum WiringPinMode { supply through a large resistor). When the pin is high, not much current flows through to ground and the line stays at positive - voltage; when the pin is low the bus + voltage; when the pin is low, the bus "drains" to ground with a small amount of current constantly flowing through the large resistor from the external supply. In this - mode no current is ever actually /sourced/ + mode, no current is ever actually sourced from the pin. */ INPUT, /**< Basic digital input. The pin voltage is sampled; when @@ -220,8 +216,5 @@ uint8 isButtonPressed(); */ uint8 waitForButtonPress(uint32 timeout_millis); -#ifdef __cplusplus -} // extern "C" -#endif #endif diff --git a/wirish/pwm.c b/wirish/pwm.c deleted file mode 100644 index 072e4cd..0000000 --- a/wirish/pwm.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * 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. - *****************************************************************************/ - -/** - * @brief Arduino-compatible PWM implementation. - */ - -#include "wirish.h" -#include "timers.h" -#include "io.h" -#include "pwm.h" - -void pwmWrite(uint8 pin, uint16 duty_cycle) { - TimerCCR ccr; - - if (pin >= NR_GPIO_PINS) { - return; - } - - ccr = PIN_MAP[pin].timer_ccr; - - if (ccr == 0) { - return; - } - - timer_pwm_write_ccr(ccr, duty_cycle); -} diff --git a/wirish/pwm.cpp b/wirish/pwm.cpp new file mode 100644 index 0000000..072e4cd --- /dev/null +++ b/wirish/pwm.cpp @@ -0,0 +1,48 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * 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. + *****************************************************************************/ + +/** + * @brief Arduino-compatible PWM implementation. + */ + +#include "wirish.h" +#include "timers.h" +#include "io.h" +#include "pwm.h" + +void pwmWrite(uint8 pin, uint16 duty_cycle) { + TimerCCR ccr; + + if (pin >= NR_GPIO_PINS) { + return; + } + + ccr = PIN_MAP[pin].timer_ccr; + + if (ccr == 0) { + return; + } + + timer_pwm_write_ccr(ccr, duty_cycle); +} diff --git a/wirish/pwm.h b/wirish/pwm.h index d0bc9e0..a6385e9 100644 --- a/wirish/pwm.h +++ b/wirish/pwm.h @@ -28,12 +28,8 @@ * @brief Arduino-compatible PWM interface. */ -#ifndef _PWM_H -#define _PWM_H - -#ifdef __cplusplus -extern "C"{ -#endif +#ifndef _PWM_H_ +#define _PWM_H_ /** * As a convenience, analogWrite is an alias of pwmWrite to ease @@ -50,10 +46,5 @@ extern "C"{ */ void pwmWrite(uint8 pin, uint16 duty_cycle); -#ifdef __cplusplus -} -#endif - - #endif diff --git a/wirish/rules.mk b/wirish/rules.mk index cb5a69f..cea34f5 100644 --- a/wirish/rules.mk +++ b/wirish/rules.mk @@ -11,21 +11,23 @@ WIRISH_INCLUDES := -I$(d) -I$(d)/comm CFLAGS_$(d) := $(WIRISH_INCLUDES) $(LIBMAPLE_INCLUDES) # Local rules and targets -cSRCS_$(d) := wirish.c \ - wirish_shift.c \ - wirish_analog.c \ - time.c \ - pwm.c \ - ext_interrupts.c \ - wirish_digital.c - -cppSRCS_$(d) := wirish_math.cpp \ - Print.cpp \ - comm/HardwareSerial.cpp \ - comm/HardwareSPI.cpp \ - usb_serial.cpp \ - HardwareTimer.cpp \ - cxxabi-compat.cpp \ +cSRCS_$(d) := + +cppSRCS_$(d) := wirish_math.cpp \ + Print.cpp \ + comm/HardwareSerial.cpp \ + comm/HardwareSPI.cpp \ + usb_serial.cpp \ + HardwareTimer.cpp \ + cxxabi-compat.cpp \ + wirish.cpp \ + wirish_shift.cpp \ + wirish_analog.cpp \ + time.cpp \ + pwm.cpp \ + ext_interrupts.cpp \ + wirish_digital.cpp \ + boards.cpp cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) cppFILES_$(d) := $(cppSRCS_$(d):%=$(d)/%) diff --git a/wirish/time.c b/wirish/time.c deleted file mode 100644 index c0a0649..0000000 --- a/wirish/time.c +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * 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. - *****************************************************************************/ - -/** - * @brief Delay implementation. - */ - -#include "libmaple.h" -#include "systick.h" -#include "time.h" - -void delay(unsigned long ms) { - uint32 i; - for (i = 0; i < ms; i++) { - delayMicroseconds(1000); - } -} - -void delayMicroseconds(uint32 us) { - /* So (2^32)/12 micros max, or less than 6 minutes */ - us *= 12; - - /* fudge for function call overhead */ - us--; - asm volatile(" mov r0, %[us] \n\t" - "1: subs r0, #1 \n\t" - " bhi 1b \n\t" - : - : [us] "r" (us) - : "r0"); -} diff --git a/wirish/time.cpp b/wirish/time.cpp new file mode 100644 index 0000000..c0a0649 --- /dev/null +++ b/wirish/time.cpp @@ -0,0 +1,52 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * 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. + *****************************************************************************/ + +/** + * @brief Delay implementation. + */ + +#include "libmaple.h" +#include "systick.h" +#include "time.h" + +void delay(unsigned long ms) { + uint32 i; + for (i = 0; i < ms; i++) { + delayMicroseconds(1000); + } +} + +void delayMicroseconds(uint32 us) { + /* So (2^32)/12 micros max, or less than 6 minutes */ + us *= 12; + + /* fudge for function call overhead */ + us--; + asm volatile(" mov r0, %[us] \n\t" + "1: subs r0, #1 \n\t" + " bhi 1b \n\t" + : + : [us] "r" (us) + : "r0"); +} diff --git a/wirish/time.h b/wirish/time.h index 8d3d074..a0c0c82 100644 --- a/wirish/time.h +++ b/wirish/time.h @@ -35,10 +35,6 @@ #include "systick.h" #include "boards.h" -#ifdef __cplusplus -extern "C"{ -#endif - #define US_PER_MS 1000 /** @@ -99,10 +95,5 @@ void delay(unsigned long ms); */ void delayMicroseconds(uint32 us); -#ifdef __cplusplus -} // extern "C" -#endif - - #endif diff --git a/wirish/wirish.c b/wirish/wirish.c deleted file mode 100644 index 4c84d26..0000000 --- a/wirish/wirish.c +++ /dev/null @@ -1,81 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * 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. - *****************************************************************************/ - -/** - * @brief generic maple board bring up: - * - * By default, we bring up all maple boards running on the stm32 to 72mhz, - * clocked off the PLL, driven by the 8MHz external crystal. - * - * AHB and APB2 are clocked at 72MHz - * APB1 is clocked at 36MHz - */ - -#include "wirish.h" -#include "systick.h" -#include "gpio.h" -#include "nvic.h" -#include "usb.h" -#include "rcc.h" -#include "fsmc.h" -#include "dac.h" -#include "flash.h" - -void init(void) { - /* make sure the flash is ready before spinning the high speed clock up */ - flash_enable_prefetch(); - flash_set_latency(FLASH_WAIT_STATE_2); - -#ifdef STM32_HIGH_DENSITY - fsmc_native_sram_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); - rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); - rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); - - nvic_init(); - systick_init(SYSTICK_RELOAD_VAL); - gpio_init(); - - /* Initialize the ADC for slow conversions, to allow for high - impedance inputs. */ - 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.cpp b/wirish/wirish.cpp new file mode 100644 index 0000000..01f4507 --- /dev/null +++ b/wirish/wirish.cpp @@ -0,0 +1,82 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * 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. + *****************************************************************************/ + +/** + * @brief generic maple board bring up: + * + * By default, we bring up all maple boards running on the stm32 to 72mhz, + * clocked off the PLL, driven by the 8MHz external crystal. + * + * AHB and APB2 are clocked at 72MHz + * APB1 is clocked at 36MHz + */ + +#include "wirish.h" +#include "systick.h" +#include "gpio.h" +#include "nvic.h" +#include "usb.h" +#include "rcc.h" +#include "fsmc.h" +#include "dac.h" +#include "flash.h" + +void init(void) { + /* make sure the flash is ready before spinning the high speed clock up */ + flash_enable_prefetch(); + flash_set_latency(FLASH_WAIT_STATE_2); + +#ifdef STM32_HIGH_DENSITY + fsmc_native_sram_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); + rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); + rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); + + nvic_init(); + systick_init(SYSTICK_RELOAD_VAL); + gpio_init_all(); + afio_init(); + + /* Initialize the ADC for slow conversions, to allow for high + impedance inputs. */ + 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.h b/wirish/wirish.h index 311c74f..447b2b6 100644 --- a/wirish/wirish.h +++ b/wirish/wirish.h @@ -32,25 +32,19 @@ #define _WIRISH_H_ #include "libmaple.h" -#include "boards.h" -#include "time.h" #include "timers.h" + +#include "boards.h" #include "io.h" #include "bits.h" #include "pwm.h" #include "ext_interrupts.h" #include "wirish_math.h" - -#ifdef __cplusplus +#include "time.h" #include "HardwareSPI.h" #include "HardwareSerial.h" #include "usb_serial.h" #include "HardwareTimer.h" -#endif - -#ifdef __cplusplus -extern "C"{ -#endif /* Arduino wiring macros and bit defines */ #define HIGH 0x1 @@ -77,9 +71,5 @@ typedef uint8 byte; void init(void); void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, byte val); -#ifdef __cplusplus -} // extern "C" -#endif - #endif diff --git a/wirish/wirish_analog.c b/wirish/wirish_analog.c deleted file mode 100644 index a658184..0000000 --- a/wirish/wirish_analog.c +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * 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. - *****************************************************************************/ - -/** - * @brief Arduino-compatible ADC implementation. - */ - -#include "libmaple.h" -#include "wirish.h" -#include "io.h" - -/* 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_channel == ADC_INVALID) { - return 0; - } - - return adc_read(ADC1, PIN_MAP[pin].adc_channel); -} diff --git a/wirish/wirish_analog.cpp b/wirish/wirish_analog.cpp new file mode 100644 index 0000000..a658184 --- /dev/null +++ b/wirish/wirish_analog.cpp @@ -0,0 +1,41 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * 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. + *****************************************************************************/ + +/** + * @brief Arduino-compatible ADC implementation. + */ + +#include "libmaple.h" +#include "wirish.h" +#include "io.h" + +/* 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_channel == ADC_INVALID) { + return 0; + } + + return adc_read(ADC1, PIN_MAP[pin].adc_channel); +} diff --git a/wirish/wirish_digital.c b/wirish/wirish_digital.c deleted file mode 100644 index bb28f0a..0000000 --- a/wirish/wirish_digital.c +++ /dev/null @@ -1,142 +0,0 @@ -/****************************************************************************** - * The MIT License - * - * Copyright (c) 2010 Perry Hung. - * - * 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. - *****************************************************************************/ - -/* - * Arduino-compatible digital I/O implementation. - */ - -#include "wirish.h" -#include "io.h" - -void pinMode(uint8 pin, WiringPinMode mode) { - uint8 outputMode; - boolean pwm = false; - - if (pin >= NR_GPIO_PINS) { - return; - } - - switch(mode) { - case OUTPUT: - outputMode = GPIO_MODE_OUTPUT_PP; - break; - case OUTPUT_OPEN_DRAIN: - outputMode = GPIO_MODE_OUTPUT_OD; - break; - case INPUT: - case INPUT_FLOATING: - outputMode = GPIO_MODE_INPUT_FLOATING; - break; - case INPUT_ANALOG: - outputMode = GPIO_MODE_INPUT_ANALOG; - break; - case INPUT_PULLUP: - outputMode = GPIO_MODE_INPUT_PU; - break; - case INPUT_PULLDOWN: - outputMode = GPIO_MODE_INPUT_PD; - break; - case PWM: - outputMode = GPIO_MODE_AF_OUTPUT_PP; - pwm = true; - break; - case PWM_OPEN_DRAIN: - outputMode = GPIO_MODE_AF_OUTPUT_OD; - pwm = true; - break; - default: - ASSERT(0); - return; - } - - gpio_set_mode(PIN_MAP[pin].port, PIN_MAP[pin].pin, outputMode); - - if (PIN_MAP[pin].timer_num != TIMER_INVALID) { - /* enable/disable timer channels if we're switching into or - out of pwm */ - if (pwm) { - timer_set_mode(PIN_MAP[pin].timer_num, - PIN_MAP[pin].timer_chan, - TIMER_PWM); - } else { - timer_set_mode(PIN_MAP[pin].timer_num, - PIN_MAP[pin].timer_chan, - TIMER_DISABLED); - } - } -} - - -uint32 digitalRead(uint8 pin) { - if (pin >= NR_GPIO_PINS) { - return 0; - } - - return gpio_read_bit(PIN_MAP[pin].port, PIN_MAP[pin].pin); -} - -void digitalWrite(uint8 pin, uint8 val) { - if (pin >= NR_GPIO_PINS) { - return; - } - - gpio_write_bit(PIN_MAP[pin].port, PIN_MAP[pin].pin, val); -} - -void togglePin(uint8 pin) { - if (pin >= NR_GPIO_PINS) { - return; - } - - gpio_toggle_pin(PIN_MAP[pin].port, PIN_MAP[pin].pin); -} - -uint8 isButtonPressed() { - if (digitalRead(BOARD_BUTTON_PIN)) { - delay(1); - while (digitalRead(BOARD_BUTTON_PIN)) - ; - return true; - } - return false; -} - -uint8 waitForButtonPress(uint32 timeout) { - uint32 start = millis(); - uint32 time; - if (timeout == 0) { - while (!isButtonPressed()) - ; - return true; - } - do { - time = millis(); - /* properly handle wrap-around */ - if ((start > time && time + (0xffffffffU - start) > timeout) || - time - start > timeout) { - return false; - } - } while (!isButtonPressed()); - return true; -} diff --git a/wirish/wirish_digital.cpp b/wirish/wirish_digital.cpp new file mode 100644 index 0000000..0c0bd85 --- /dev/null +++ b/wirish/wirish_digital.cpp @@ -0,0 +1,143 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010 Perry Hung. + * + * 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. + *****************************************************************************/ + +/* + * Arduino-compatible digital I/O implementation. + */ + +#include "wirish.h" +#include "io.h" + +void pinMode(uint8 pin, WiringPinMode mode) { + gpio_pin_mode outputMode; + boolean pwm = false; + + if (pin >= NR_GPIO_PINS) { + return; + } + + switch(mode) { + case OUTPUT: + outputMode = GPIO_OUTPUT_PP; + break; + case OUTPUT_OPEN_DRAIN: + outputMode = GPIO_OUTPUT_OD; + break; + case INPUT: + case INPUT_FLOATING: + outputMode = GPIO_INPUT_FLOATING; + break; + case INPUT_ANALOG: + outputMode = GPIO_INPUT_ANALOG; + break; + case INPUT_PULLUP: + outputMode = GPIO_INPUT_PU; + break; + case INPUT_PULLDOWN: + outputMode = GPIO_INPUT_PD; + break; + case PWM: + outputMode = GPIO_AF_OUTPUT_PP; + pwm = true; + break; + case PWM_OPEN_DRAIN: + outputMode = GPIO_AF_OUTPUT_OD; + pwm = true; + break; + default: + ASSERT(0); + return; + } + + gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].pin, outputMode); + + if (PIN_MAP[pin].timer_num != TIMER_INVALID) { + /* enable/disable timer channels if we're switching into or + out of pwm */ + if (pwm) { + timer_set_mode(PIN_MAP[pin].timer_num, + PIN_MAP[pin].timer_chan, + TIMER_PWM); + } else { + timer_set_mode(PIN_MAP[pin].timer_num, + PIN_MAP[pin].timer_chan, + TIMER_DISABLED); + } + } +} + + +uint32 digitalRead(uint8 pin) { + if (pin >= NR_GPIO_PINS) { + return 0; + } + + return gpio_read_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].pin) ? + HIGH : LOW; +} + +void digitalWrite(uint8 pin, uint8 val) { + if (pin >= NR_GPIO_PINS) { + return; + } + + gpio_write_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].pin, val); +} + +void togglePin(uint8 pin) { + if (pin >= NR_GPIO_PINS) { + return; + } + + gpio_toggle_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].pin); +} + +uint8 isButtonPressed() { + if (digitalRead(BOARD_BUTTON_PIN)) { + delay(1); + while (digitalRead(BOARD_BUTTON_PIN)) + ; + return true; + } + return false; +} + +uint8 waitForButtonPress(uint32 timeout) { + uint32 start = millis(); + uint32 time; + if (timeout == 0) { + while (!isButtonPressed()) + ; + return true; + } + do { + time = millis(); + /* properly handle wrap-around */ + if ((start > time && time + (0xffffffffU - start) > timeout) || + time - start > timeout) { + return false; + } + } while (!isButtonPressed()); + return true; +} diff --git a/wirish/wirish_math.h b/wirish/wirish_math.h index 14614ba..fa544a9 100644 --- a/wirish/wirish_math.h +++ b/wirish/wirish_math.h @@ -24,7 +24,7 @@ /** * @file wirish_math.h - * @brief Includes cmath; provides Arduino-compatible math routines. + * @brief Includes ; provides Arduino-compatible math routines. */ #ifndef _WIRING_MATH_H_ @@ -32,8 +32,6 @@ #include -#ifdef __cplusplus - /** * @brief Initialize the pseudo-random number generator. * @param seed the number used to initialize the seed; cannot be zero. @@ -78,8 +76,7 @@ long random(long min, long max); * @param toEnd the end of the value's mapped range. * @return the mapped value. */ -/* TODO: profile code bloat due to inlining this */ -inline long map(long value, long fromStart, long fromEnd, +static inline long map(long value, long fromStart, long fromEnd, long toStart, long toEnd) { return (value - fromStart) * (toEnd - toStart) / (fromEnd - fromStart) + toStart; @@ -105,8 +102,6 @@ inline long map(long value, long fromStart, long fromEnd, #endif #define abs(x) (((x) > 0) ? (x) : -(unsigned)(x)) -#endif - /* Following are duplicate declarations (with Doxygen comments) for * some of the math.h functions; this is for the convenience of the * Sphinx docs. diff --git a/wirish/wirish_shift.c b/wirish/wirish_shift.c deleted file mode 100644 index f67364d..0000000 --- a/wirish/wirish_shift.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * wiring_shift.c - shiftOut() function - * Part of Arduino - http://www.arduino.cc/ - * - * Copyright (c) 2005-2006 David A. Mellis - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - * $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ - */ - -#include "wirish.h" - -void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 val) { - int i; - - for (i = 0; i < 8; i++) { - if (bitOrder == LSBFIRST) { - digitalWrite(dataPin, !!(val & (1 << i))); - } else { - digitalWrite(dataPin, !!(val & (1 << (7 - i)))); - } - - digitalWrite(clockPin, HIGH); - digitalWrite(clockPin, LOW); - } -} diff --git a/wirish/wirish_shift.cpp b/wirish/wirish_shift.cpp new file mode 100644 index 0000000..f67364d --- /dev/null +++ b/wirish/wirish_shift.cpp @@ -0,0 +1,40 @@ +/* + * wiring_shift.c - shiftOut() function + * Part of Arduino - http://www.arduino.cc/ + * + * Copyright (c) 2005-2006 David A. Mellis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ + */ + +#include "wirish.h" + +void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 val) { + int i; + + for (i = 0; i < 8; i++) { + if (bitOrder == LSBFIRST) { + digitalWrite(dataPin, !!(val & (1 << i))); + } else { + digitalWrite(dataPin, !!(val & (1 << (7 - i)))); + } + + digitalWrite(clockPin, HIGH); + digitalWrite(clockPin, LOW); + } +} -- cgit v1.2.3 From 4862d1eae5813e278cfbb1d5e0a040010b92eb3f Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Wed, 16 Mar 2011 17:37:21 -0400 Subject: Maple RET6 edition support --- Makefile | 7 ++++ examples/test-session.cpp | 9 ++--- libmaple/libmaple.h | 7 +++- libmaple/pwr.c | 2 +- libmaple/rules.mk | 1 + libmaple/usb/usb_config.h | 10 ++--- support/ld/maple_RET6/flash.ld | 18 +++++++++ support/ld/maple_RET6/jtag.ld | 17 ++++++++ support/ld/maple_RET6/ram.ld | 18 +++++++++ support/ld/maple_native/ram.ld | 1 - support/scripts/copy-to-ide | 18 ++++++--- wirish/boards.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++ wirish/boards.h | 15 +++++++ wirish/wirish.cpp | 2 +- 14 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 support/ld/maple_RET6/flash.ld create mode 100644 support/ld/maple_RET6/jtag.ld create mode 100644 support/ld/maple_RET6/ram.ld (limited to 'libmaple/usb') diff --git a/Makefile b/Makefile index 3804421..d31c9ed 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,13 @@ ifeq ($(BOARD), maple_mini) ERROR_LED_PIN := 1 DENSITY := STM32_MEDIUM_DENSITY endif +ifeq ($(BOARD), maple_RET6) + MCU := STM32F103RE + PRODUCT_ID := 0003 + ERROR_LED_PORT := GPIOA + ERROR_LED_PIN := 5 + DENSITY := STM32_HIGH_DENSITY +endif # Useful paths ifeq ($(LIB_MAPLE_HOME),) diff --git a/examples/test-session.cpp b/examples/test-session.cpp index ea631ca..a147e06 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -20,7 +20,7 @@ int rate = 0; -#if defined(BOARD_maple) +#if defined(BOARD_maple) || defined(BOARD_maple_RET6) const uint8 pwm_pins[] = {0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 25, 27, 28}; const uint8 adc_pins[] = @@ -617,15 +617,14 @@ void init_all_timers(uint16 prescale) { timer_init(TIMER4, prescale); #ifdef STM32_HIGH_DENSITY timer_init(TIMER5, prescale); - timer_init(TIMER6, prescale); - timer_init(TIMER7, prescale); + // timer_init(TIMER6, prescale); + // timer_init(TIMER7, prescale); timer_init(TIMER8, prescale); #endif } - // Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated object that need libmaple may fail. +// Otherwise, statically allocated objects that need libmaple may fail. __attribute__(( constructor )) void premain() { init(); } diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h index 0bbd34e..7814730 100644 --- a/libmaple/libmaple.h +++ b/libmaple/libmaple.h @@ -56,7 +56,6 @@ /* e.g., LeafLabs Maple Native */ #define NR_GPIO_PORTS 7 - #define SRAM_SIZE 0x10000 #elif defined(MCU_STM32F103CB) @@ -69,6 +68,12 @@ #define SRAM_SIZE 0x5000 +#elif defined(MCU_STM32F103RE) + /* e.g., LeafLabs Maple RET6 edition */ + + #define NR_GPIO_PORTS 4 + #define SRAM_SIZE 0x10000 + #else #error "No MCU type specified. Add something like -DMCU_STM32F103RB " \ diff --git a/libmaple/pwr.c b/libmaple/pwr.c index b43193e..d63a92d 100644 --- a/libmaple/pwr.c +++ b/libmaple/pwr.c @@ -28,7 +28,7 @@ #include "rcc.h" pwr_dev pwr = { - .regs = PWR_BASE; + .regs = PWR_BASE, }; const pwr_dev *PWR = &pwr; diff --git a/libmaple/rules.mk b/libmaple/rules.mk index b87595d..b264b96 100644 --- a/libmaple/rules.mk +++ b/libmaple/rules.mk @@ -22,6 +22,7 @@ cSRCS_$(d) := adc.c \ gpio.c \ iwdg.c \ nvic.c \ + pwr.c \ rcc.c \ spi.c \ syscalls.c \ diff --git a/libmaple/usb/usb_config.h b/libmaple/usb/usb_config.h index 9003da9..0860b90 100644 --- a/libmaple/usb/usb_config.h +++ b/libmaple/usb/usb_config.h @@ -28,7 +28,7 @@ #define RESET_DELAY (100) #define USB_CONFIG_MAX_POWER (100 >> 1) -#if defined(BOARD_maple) +#if defined(BOARD_maple) || defined(BOARD_maple_RET6) /* USB Identifier numbers */ #define VCOM_ID_PRODUCT 0x0004 @@ -37,13 +37,13 @@ #elif defined(BOARD_maple_mini) - #define VCOM_ID_PRODUCT 0x0005 + #define VCOM_ID_PRODUCT 0x0004 #define USB_DISC_DEV GPIOB #define USB_DISC_PIN 9 #elif defined(BOARD_maple_native) - #define VCOM_ID_PRODUCT 0x0006 + #define VCOM_ID_PRODUCT 0x0004 #define USB_DISC_DEV GPIOB #define USB_DISC_PIN 8 @@ -51,8 +51,8 @@ #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. " \ + "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.") diff --git a/support/ld/maple_RET6/flash.ld b/support/ld/maple_RET6/flash.ld new file mode 100644 index 0000000..2a4f0c7 --- /dev/null +++ b/support/ld/maple_RET6/flash.ld @@ -0,0 +1,18 @@ +/* + * STM32F103RET6 high density chip linker script for use with Maple + * bootloader. Loads to Flash. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); + +INCLUDE common_rom.inc diff --git a/support/ld/maple_RET6/jtag.ld b/support/ld/maple_RET6/jtag.ld new file mode 100644 index 0000000..88f45e0 --- /dev/null +++ b/support/ld/maple_RET6/jtag.ld @@ -0,0 +1,17 @@ +/* + * STM32F103RET6 high density bare metal linker script. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", rom); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); + +INCLUDE common_rom.inc diff --git a/support/ld/maple_RET6/ram.ld b/support/ld/maple_RET6/ram.ld new file mode 100644 index 0000000..f09acd9 --- /dev/null +++ b/support/ld/maple_RET6/ram.ld @@ -0,0 +1,18 @@ +/* + * STM32F103RET6 high density chip linker script for use with Maple + * bootloader. Loads to RAM. + */ + +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K + rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K +} + +GROUP(libcs3_stm32_high_density.a) + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_DATA", ram); +REGION_ALIAS("REGION_BSS", ram); + +INCLUDE common_ram.inc diff --git a/support/ld/maple_native/ram.ld b/support/ld/maple_native/ram.ld index 22c09cd..d5bd3b0 100644 --- a/support/ld/maple_native/ram.ld +++ b/support/ld/maple_native/ram.ld @@ -19,4 +19,3 @@ REGION_ALIAS("REGION_DATA", ram); REGION_ALIAS("REGION_BSS", ram); INCLUDE common_ram.inc - diff --git a/support/scripts/copy-to-ide b/support/scripts/copy-to-ide index 301126d..5254974 100755 --- a/support/scripts/copy-to-ide +++ b/support/scripts/copy-to-ide @@ -1,7 +1,8 @@ #!/bin/sh -# This hack copies the necessary library files into the Maple IDE -# repository. +# This hack copies libmaple's source, linker scripts, and built +# documentation into the Maple IDE repository (which is expected as +# its first argument). DEST=$1 @@ -18,14 +19,18 @@ LMAPLE_SRC="LICENSE ./libmaple/usb/usb_lib/*.h ./libmaple/usb/usb_lib/*.c ./wirish/*.h - ./wirish/*.c ./wirish/main.cxx ./wirish/*.cpp ./wirish/comm/*.cpp ./wirish/comm/*.h + ./support/ld/common_ram.inc + ./support/ld/common_rom.inc + ./support/ld/libcs3_stm32_high_density.a + ./support/ld/libcs3_stm32_med_density.a ./support/ld/maple + ./support/ld/maple_mini ./support/ld/maple_native - ./support/ld/libcs3-lanchon-stm32.a + ./support/ld/maple_RET6 ./support/ld/names.inc" LMAPLE_DOCS=./docs @@ -40,7 +45,8 @@ fi # source echo Copying libmaple source -rm -rf $DEST_CORES/*.c $DEST_CORES/*.cpp $DEST_CORES/*.h $DEST_CORES/*.cxx $DEST_CORES/*.inc $DEST_CORES/*.a $DEST_CORES/*.S $DEST_CORES/maple $DEST_CORES/maple_native +rm -rf $DEST_CORES/*.c $DEST_CORES/*.cpp $DEST_CORES/*.h $DEST_CORES/*.cxx $DEST_CORES/*.S +rm -rf $DEST_CORES/*.inc $DEST_CORES/*.a $DEST_CORES/maple $DEST_CORES/maple_* cp -R $LMAPLE_SRC $DEST_CORES echo Copying over libraries @@ -51,7 +57,7 @@ echo Deleting old reference directory contents rm -rf $DEST_REF/* echo Rebuilding documentation -( cd $LMAPLE_DOCS; doxygen && make clean 2>/dev/null 1>/dev/null && make html ) +( cd $LMAPLE_DOCS; doxygen >/dev/null 2>&1 && make clean >/dev/null 2>&1 && make html ) echo Copying over documentation cp -R $LMAPLE_DOCS_BUILD/* $DEST_REF diff --git a/wirish/boards.cpp b/wirish/boards.cpp index 440218b..66f008f 100644 --- a/wirish/boards.cpp +++ b/wirish/boards.cpp @@ -380,6 +380,95 @@ PinMapping PIN_MAP[NR_GPIO_PINS] = { {GPIOB, 1, 9, TIMER3_CH4_CCR, TIMER3, 4, AFIO_EXTI_PB}, }; +#elif defined(BOARD_maple_RET6) + +PinMapping PIN_MAP[NR_GPIO_PINS] = { + /* D0/PA3 */ + {GPIOA, 3, 3, TIMER2_CH4_CCR, TIMER2, 4, AFIO_EXTI_PA}, + /* D1/PA2 */ + {GPIOA, 2, 2, TIMER2_CH3_CCR, TIMER2, 3, AFIO_EXTI_PA}, + /* D2/PA0 */ + {GPIOA, 0, 0, TIMER2_CH1_CCR, TIMER2, 1, AFIO_EXTI_PA}, + /* D3/PA1 */ + {GPIOA, 1, 1, TIMER2_CH2_CCR, TIMER2, 2, AFIO_EXTI_PA}, + /* D4/PB5 */ + {GPIOB, 5, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D5/PB6 */ + {GPIOB, 6, ADCx, TIMER4_CH1_CCR, TIMER4, 1, AFIO_EXTI_PB}, + /* D6/PA8 */ + {GPIOA, 8, ADCx, TIMER1_CH1_CCR, TIMER1, 1, AFIO_EXTI_PA}, + /* D7/PA9 */ + {GPIOA, 9, ADCx, TIMER1_CH2_CCR, TIMER1, 2, AFIO_EXTI_PA}, + /* D8/PA10 */ + {GPIOA, 10, ADCx, TIMER1_CH3_CCR, TIMER1, 3, AFIO_EXTI_PA}, + /* D9/PB7 */ + {GPIOB, 7, ADCx, TIMER4_CH2_CCR, TIMER4, 2, AFIO_EXTI_PB}, + /* D10/PA4 */ + {GPIOA, 4, 4, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D11/PA7 */ + {GPIOA, 7, 7, TIMER3_CH2_CCR, TIMER3, 2, AFIO_EXTI_PA}, + /* D12/PA6 */ + {GPIOA, 6, 6, TIMER3_CH1_CCR, TIMER3, 1, AFIO_EXTI_PA}, + /* D13/PA5 */ + {GPIOA, 5, 5, 0, TIMERx, TIMERx, AFIO_EXTI_PA}, + /* D14/PB8 */ + {GPIOB, 8, ADCx, TIMER4_CH3_CCR, TIMER4, 3, AFIO_EXTI_PB}, + + /* Little header */ + + /* D15/PC0 */ + {GPIOC, 0, 10, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D16/PC1 */ + {GPIOC, 1, 11, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D17/PC2 */ + {GPIOC, 2, 12, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D18/PC3 */ + {GPIOC, 3, 13, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D19/PC4 */ + {GPIOC, 4, 14, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D20/PC5 */ + {GPIOC, 5, 15, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + + /* External header */ + + /* D21/PC13 */ + {GPIOC, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D22/PC14 */ + {GPIOC, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D23/PC15 */ + {GPIOC, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D24/PB9 */ + {GPIOB, 9, ADCx, TIMER4_CH4_CCR, TIMER4, 4, AFIO_EXTI_PB}, + /* D25/PD2 */ + {GPIOD, 2, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PD}, + /* D26/PC10 */ + {GPIOC, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PC}, + /* D27/PB0 */ + {GPIOB, 0, 8, TIMER3_CH3_CCR, TIMER3, 3, AFIO_EXTI_PB}, + /* D28/PB1 */ + {GPIOB, 1, 9, TIMER3_CH4_CCR, TIMER3, 4, AFIO_EXTI_PB}, + /* D29/PB10 */ + {GPIOB, 10, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D30/PB11 */ + {GPIOB, 11, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D31/PB12 */ + {GPIOB, 12, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D32/PB13 */ + {GPIOB, 13, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D33/PB14 */ + {GPIOB, 14, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D34/PB15 */ + {GPIOB, 15, ADCx, 0, TIMERx, TIMERx, AFIO_EXTI_PB}, + /* D35/PC6 */ + {GPIOC, 6, ADCx, TIMER8_CH1_CCR, TIMER8, 1, AFIO_EXTI_PC}, + /* D36/PC7 */ + {GPIOC, 7, ADCx, TIMER8_CH1_CCR, TIMER8, 2, AFIO_EXTI_PC}, + /* D37/PC8 */ + {GPIOC, 8, ADCx, TIMER8_CH1_CCR, TIMER8, 3, AFIO_EXTI_PC}, + /* D38/PC9 (BUT) */ + {GPIOC, 9, ADCx, TIMER8_CH1_CCR, TIMER8, 4, AFIO_EXTI_PC} +}; + #else #error "Board type has not been selected correctly." diff --git a/wirish/boards.h b/wirish/boards.h index 2941127..94566fa 100644 --- a/wirish/boards.h +++ b/wirish/boards.h @@ -113,6 +113,21 @@ extern PinMapping PIN_MAP[]; afio_mapr_swj_config(AFIO_MAPR_SWJ_NO_JTAG_NO_SW); \ } while (0) +#elif defined(BOARD_maple_RET6) + + #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 + + /* Total number of GPIO pins that are broken out to headers and + intended for general use. */ + #define NR_GPIO_PINS 39 + + #define BOARD_INIT do { \ + } while(0) + #else #error "Board type has not been selected correctly." diff --git a/wirish/wirish.cpp b/wirish/wirish.cpp index 6967489..6d77bc8 100644 --- a/wirish/wirish.cpp +++ b/wirish/wirish.cpp @@ -47,7 +47,7 @@ void init(void) { flash_enable_prefetch(); flash_set_latency(FLASH_WAIT_STATE_2); -#ifdef STM32_HIGH_DENSITY +#ifdef BOARD_maple_native fsmc_native_sram_init(); #endif -- cgit v1.2.3 From 77a0f70e491da2a26323d24b4c1d65320996c469 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Thu, 17 Mar 2011 07:47:19 -0400 Subject: Fixing typo in libmaple/usb/descriptors.h; thanks, StephenFromNYC! http://forums.leaflabs.com/topic.php?id=687 --- libmaple/usb/descriptors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libmaple/usb') diff --git a/libmaple/usb/descriptors.h b/libmaple/usb/descriptors.h index 6f7d08b..460a88c 100644 --- a/libmaple/usb/descriptors.h +++ b/libmaple/usb/descriptors.h @@ -61,7 +61,7 @@ extern "C" { uint16 bString[len]; \ } -#define CDC_FUCNTIONAL_DESCRIPTOR(DataSize) \ +#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ struct \ { \ uint8 bLength; \ -- cgit v1.2.3 From 4a56b462cfa7c54c623374f966b853a7b0790613 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Mon, 11 Apr 2011 20:45:35 -0400 Subject: Resolving some FIXMEs. --- examples/test-session.cpp | 10 ++++++++-- examples/vga-scope.cpp | 7 ++++++- libmaple/usb/usb.c | 24 ++---------------------- libmaple/usb/usb_config.h | 2 +- 4 files changed, 17 insertions(+), 26 deletions(-) (limited to 'libmaple/usb') diff --git a/examples/test-session.cpp b/examples/test-session.cpp index 03fb248..01dd184 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -780,17 +780,23 @@ void init_all_timers(uint16 prescale) { } void enable_usarts(void) { - // FIXME generalize after USART refactor Serial1.begin(BAUD); Serial2.begin(BAUD); Serial3.begin(BAUD); +#ifdef STM32_HIGH_DENSITY + Serial4.begin(BAUD); + Serial5.begin(BAUD); +#endif } void disable_usarts(void) { - // FIXME generalize after USART refactor Serial1.end(); Serial2.end(); Serial3.end(); +#ifdef STM32_HIGH_DENSITY + Serial4.end(); + Serial5.end(); +#endif } void print_board_array(const char* msg, const uint8 arr[], int len) { diff --git a/examples/vga-scope.cpp b/examples/vga-scope.cpp index 9c6dca5..66e72e9 100644 --- a/examples/vga-scope.cpp +++ b/examples/vga-scope.cpp @@ -28,12 +28,17 @@ - http://www.epanorama.net/documents/pc/vga_timing.html This code is released into the public domain. + + Authors: + + Bryan Newbold + Marti Bolivar */ #include "wirish.h" #include "systick.h" -// FIXME generalize for Native and Mini +// FIXME: generalize for Native and Mini #define LED_PIN BOARD_LED_PIN #define ANALOG_PIN 18 diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c index 2fc4eb2..7b1dd4c 100644 --- a/libmaple/usb/usb.c +++ b/libmaple/usb/usb.c @@ -35,6 +35,7 @@ #include "usb_lib.h" #include "gpio.h" #include "usb_hardware.h" +#include "delay.h" #include "usb_config.h" #include "usb_callbacks.h" @@ -318,29 +319,8 @@ if (wIstr & ISTR_CTR & wInterrupt_Mask) { } -static void FIXME_delayMicroseconds_copy(uint32 us) { - /* So (2^32)/12 micros max, or less than 6 minutes */ - us *= 12; - - /* fudge for function call overhead */ - us--; - asm volatile(" mov r0, %[us] \n\t" - "1: subs r0, #1 \n\t" - " bhi 1b \n\t" - : - : [us] "r" (us) - : "r0"); -} - -static void FIXME_delay_copy(unsigned long ms) { - uint32 i; - for (i = 0; i < ms; i++) { - FIXME_delayMicroseconds_copy(1000); - } -} - void usbWaitReset(void) { - FIXME_delay_copy(RESET_DELAY); + delay_us(RESET_DELAY); systemHardReset(); } diff --git a/libmaple/usb/usb_config.h b/libmaple/usb/usb_config.h index 0860b90..23b49ee 100644 --- a/libmaple/usb/usb_config.h +++ b/libmaple/usb/usb_config.h @@ -25,7 +25,7 @@ *****************************************************************************/ #define VCOM_ID_VENDOR 0x1EAF -#define RESET_DELAY (100) +#define RESET_DELAY (100000) #define USB_CONFIG_MAX_POWER (100 >> 1) #if defined(BOARD_maple) || defined(BOARD_maple_RET6) -- cgit v1.2.3 From f3bcdd18d8f0b64cd8f17410b480b49315791544 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Wed, 4 May 2011 13:15:33 -0400 Subject: SerialUSB fixups. --- docs/source/lang/api/serialusb.rst | 15 +++-- libmaple/usb/usb.c | 12 ++-- libmaple/usb/usb.h | 2 +- libmaple/usb/usb_lib/usb_mem.c | 4 +- libmaple/usb/usb_lib/usb_mem.h | 2 +- wirish/Print.cpp | 2 +- wirish/Print.h | 4 +- wirish/usb_serial.cpp | 117 ++++++++++++++----------------------- wirish/usb_serial.h | 8 ++- 9 files changed, 67 insertions(+), 99 deletions(-) (limited to 'libmaple/usb') diff --git a/docs/source/lang/api/serialusb.rst b/docs/source/lang/api/serialusb.rst index ee7146e..ed466f2 100644 --- a/docs/source/lang/api/serialusb.rst +++ b/docs/source/lang/api/serialusb.rst @@ -16,9 +16,8 @@ Introduction In addition to three :ref:`serial ports `, the Maple's STM32 microprocessor includes a dedicated USB peripheral. This peripheral is used to emulate a regular serial port for use as a -terminal (text read/write). The emulated terminal is relatively slow -and inefficient; it is best for transferring data at regular serial -speeds (kilobaud). +terminal. The emulated terminal is relatively slow; it is best for +transferring data at regular serial speeds (kilobaud). Library access to the emulated serial port is provided through the ``SerialUSB`` object. You can mostly use ``SerialUSB`` as a drop-in @@ -30,14 +29,14 @@ replacement for ``Serial1``, ``Serial2``, and ``Serial3``. This means that if you have a number of calls to one of the ``SerialUSB`` ``write()`` or ``print()`` functions in your code, - and you are not monitoring the emulated on a computer, your program - will run much, much slower than if it is being monitored or totally - disconnected (run off of a battery). + and you are not monitoring ``SerialUSB`` on a computer, your + program will run much slower than if it is being monitored or + totally disconnected (run off of a battery). You can avoid this behavior by :ref:`deciphering the port status - using the DTR and RTS line status `; the + using the DTR and RTS line status ` (the behavior of these control lines is platform dependent and we no - longer interpret them by default. + longer interpret them by default). Library Documentation --------------------- diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c index 7b1dd4c..b34c4b6 100644 --- a/libmaple/usb/usb.c +++ b/libmaple/usb/usb.c @@ -343,23 +343,21 @@ void usbBlockingSendByte(char ch) { countTx = 1; while (countTx); } -uint32 usbSendBytes(uint8* sendBuf, uint32 len) { - /* any checks on connection (via dtr/rts) done upstream in wirish or - by user */ - /* last xmit hasnt finished, abort */ +uint32 usbSendBytes(const uint8* sendBuf, uint32 len) { + /* Last transmission hasn't finished, abort */ if (countTx) { return 0; } // We can only put VCOM_TX_EPSIZE bytes in the buffer - if(len > VCOM_TX_EPSIZE/2) { - len = VCOM_TX_EPSIZE/2; + if (len > VCOM_TX_EPSIZE / 2) { + len = VCOM_TX_EPSIZE / 2; } // Try to load some bytes if we can if (len) { - UserToPMABufferCopy(sendBuf,VCOM_TX_ADDR, len); + UserToPMABufferCopy(sendBuf, VCOM_TX_ADDR, len); _SetEPTxCount(VCOM_TX_ENDP, len); countTx += len; _SetEPTxValid(VCOM_TX_ENDP); diff --git a/libmaple/usb/usb.h b/libmaple/usb/usb.h index 92f606c..c724c54 100644 --- a/libmaple/usb/usb.h +++ b/libmaple/usb/usb.h @@ -74,7 +74,7 @@ void usbWaitReset(void); /* blocking functions for send/receive */ void usbBlockingSendByte(char ch); -uint32 usbSendBytes(uint8* sendBuf,uint32 len); +uint32 usbSendBytes(const uint8* sendBuf,uint32 len); uint32 usbBytesAvailable(void); uint32 usbReceiveBytes(uint8* recvBuf, uint32 len); uint8 usbGetDTR(void); diff --git a/libmaple/usb/usb_lib/usb_mem.c b/libmaple/usb/usb_lib/usb_mem.c index ee698c5..90ffc62 100644 --- a/libmaple/usb/usb_lib/usb_mem.c +++ b/libmaple/usb/usb_lib/usb_mem.c @@ -30,9 +30,9 @@ * - wPMABufAddr: address into PMA. * - wNBytes: no. of bytes to be copied. * Output : None. -* Return : None . +* Return : None . *******************************************************************************/ -void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) +void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) { u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */ u32 i, temp1, temp2; diff --git a/libmaple/usb/usb_lib/usb_mem.h b/libmaple/usb/usb_lib/usb_mem.h index a3d7927..60ff9f1 100644 --- a/libmaple/usb/usb_lib/usb_mem.h +++ b/libmaple/usb/usb_lib/usb_mem.h @@ -26,7 +26,7 @@ extern "C" { #endif -void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); +void UserToPMABufferCopy(const u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); #if defined(__cplusplus) diff --git a/wirish/Print.cpp b/wirish/Print.cpp index cfb2cda..9130c9c 100644 --- a/wirish/Print.cpp +++ b/wirish/Print.cpp @@ -52,7 +52,7 @@ void Print::write(const char *str) { } } -void Print::write(void *buffer, uint32 size) { +void Print::write(const void *buffer, uint32 size) { uint8 *ch = (uint8*)buffer; while (size--) { write(*ch++); diff --git a/wirish/Print.h b/wirish/Print.h index ec7b163..73d82e7 100644 --- a/wirish/Print.h +++ b/wirish/Print.h @@ -35,9 +35,9 @@ enum { class Print { public: - virtual void write(uint8) = 0; + virtual void write(uint8 ch) = 0; virtual void write(const char *str); - virtual void write(void*, uint32); + virtual void write(const void *buf, uint32 len); void print(char); void print(const char[]); void print(uint8); diff --git a/wirish/usb_serial.cpp b/wirish/usb_serial.cpp index e2751a2..0a2be43 100644 --- a/wirish/usb_serial.cpp +++ b/wirish/usb_serial.cpp @@ -3,28 +3,29 @@ * * Copyright (c) 2010 Perry Hung. * - * 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 + * 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 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. + * 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. *****************************************************************************/ /** - * @brief Wirish USB class for easy communication, uses libmaple's - * virtual com port implementation + * @brief USB virtual serial terminal */ #include @@ -34,7 +35,7 @@ #define USB_TIMEOUT 50 -USBSerial :: USBSerial(void) { +USBSerial::USBSerial(void) { } void USBSerial::begin(void) { @@ -46,54 +47,29 @@ void USBSerial::end(void) { } void USBSerial::write(uint8 ch) { - if(!(usbIsConnected() && usbIsConfigured())) { - return; - } - - uint16 status = 0; - uint32 start = millis(); - - while(status == 0 && (millis() - start <= USB_TIMEOUT)) { - status = usbSendBytes(&ch, 1); - } + const uint8 buf[] = {ch}; + this->write(buf, 1); } void USBSerial::write(const char *str) { - if(!(usbIsConnected() && usbIsConfigured())) { - return; - } - - uint32 len = strlen(str); - uint16 status = 0; - uint16 oldstatus = 0; - uint32 start = millis(); - - while(status < len && (millis() - start < USB_TIMEOUT)) { - status += usbSendBytes((uint8*)str+status, len-status); - if(oldstatus != status) - start = millis(); - oldstatus = status; - } + this->write(str, strlen(str)); } -void USBSerial::write(void *buf, uint32 size) { - if(!(usbIsConnected() && usbIsConfigured())) { +void USBSerial::write(const void *buf, uint32 len) { + if (!(usbIsConnected() && usbIsConfigured()) || !buf) { return; } - if (!buf) { - return; - } - - uint16 status = 0; - uint16 oldstatus = 0; + uint32 txed = 0; + uint32 old_txed = 0; uint32 start = millis(); - while(status < size && (millis() - start < USB_TIMEOUT)) { - status += usbSendBytes((uint8*)buf+status, size-status); - if(oldstatus != status) + while (txed < len && (millis() - start < USB_TIMEOUT)) { + txed += usbSendBytes((const uint8*)buf + txed, len - txed); + if (old_txed != txed) { start = millis(); - oldstatus = status; + } + old_txed = txed; } } @@ -101,47 +77,40 @@ uint32 USBSerial::available(void) { return usbBytesAvailable(); } -/* blocks forever until len_bytes is received */ uint32 USBSerial::read(void *buf, uint32 len) { - if (buf == 0) { + if (!buf) { return 0; } - uint32 bytes_in = 0; - while (len > 0) { - uint32 new_bytes = usbReceiveBytes((uint8*)buf + bytes_in, len); - len -= new_bytes; - bytes_in += new_bytes; + uint32 rxed = 0; + while (rxed < len) { + rxed += usbReceiveBytes((uint8*)buf + rxed, len - rxed); } - return bytes_in; + return rxed; } -/* blocks forever until 1 byte is received */ +/* Blocks forever until 1 byte is received */ uint8 USBSerial::read(void) { - uint8 ch; - - while (usbReceiveBytes(&ch, 1) == 0); - return ch; + uint8 buf[1]; + this->read(buf, 1); + return buf[0]; } uint8 USBSerial::pending(void) { return usbGetPending(); } -// TODO deprecate the crap out of this +uint8 USBSerial::isConnected(void) { + return usbIsConnected() && usbIsConfigured(); +} + uint8 USBSerial::getDTR(void) { return usbGetDTR(); } -// TODO deprecate the crap out of this uint8 USBSerial::getRTS(void) { return usbGetRTS(); } -uint8 USBSerial::isConnected(void) { - return (usbIsConnected() && usbIsConfigured()); -} - USBSerial SerialUSB; - diff --git a/wirish/usb_serial.h b/wirish/usb_serial.h index c228837..ba9e18c 100644 --- a/wirish/usb_serial.h +++ b/wirish/usb_serial.h @@ -23,8 +23,7 @@ *****************************************************************************/ /** - * @brief wirish usb class for easy goin communication, uses libmaple's - * virtual com port implementation + * @brief Wirish virtual serial port */ #ifndef _USB_SERIAL_H_ @@ -32,6 +31,9 @@ #include "Print.h" +/** + * @brief Virtual serial terminal. + */ class USBSerial : public Print { public: USBSerial(void); @@ -46,7 +48,7 @@ public: void write(uint8); void write(const char *str); - void write(void *, uint32); + void write(const void*, uint32); uint8 getRTS(); uint8 getDTR(); -- cgit v1.2.3