From 1cec807e44da29c5a122e57120174f4711d95f25 Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Tue, 14 Sep 2010 21:59:39 -0400 Subject: Fix enable/disable global irq Oooooops. --- libmaple/nvic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libmaple') diff --git a/libmaple/nvic.h b/libmaple/nvic.h index 4f4972d..3286357 100644 --- a/libmaple/nvic.h +++ b/libmaple/nvic.h @@ -73,8 +73,8 @@ enum { }; -#define nvic_globalirq_enable() asm volatile("cpsid i") -#define nvic_globalirq_disable() asm volatile("cpsie i") +#define nvic_globalirq_enable() asm volatile("cpsie i") +#define nvic_globalirq_disable() asm volatile("cpsid i") void nvic_init(void); void nvic_irq_enable(uint32 device); -- cgit v1.2.3 From 9180233b971aecb621ae54307c72ef074773640f Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Tue, 14 Sep 2010 23:09:38 -0400 Subject: Check different set of flags for SPI master transmit Tested on wishield, would like some more testing if anybody has more things that speak spi --- libmaple/spi.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'libmaple') diff --git a/libmaple/spi.c b/libmaple/spi.c index 68855a5..4b02f44 100644 --- a/libmaple/spi.c +++ b/libmaple/spi.c @@ -115,14 +115,14 @@ void spi_init(uint32 spi_num, uint8 spi_tx_byte(uint32 spi_num, uint8 data) { SPI *spi; - ASSERT(spi_num == 1 || spi_num == 2); - spi = (spi_num == 1) ? (SPI*)SPI1_BASE : (SPI*)SPI2_BASE; + while (!(spi->SR & SR_TXE)) + ; + spi->DR = data; - while (!(spi->SR & SR_TXE) || - (spi->SR & SR_BSY)) + while (!(spi->SR & SR_RXNE)) ; return spi->DR; @@ -141,11 +141,14 @@ uint8 spi_tx(uint32 spi_num, uint8 *buf, uint32 len) { } while (i < len) { + while (!(spi->SR & SR_TXE)) + ; + spi->DR = buf[i]; - while (!(spi->SR & SR_TXE) || - (spi->SR & SR_BSY) || - !(spi->SR & SR_RXNE)) + + while (!(spi->SR & SR_RXNE)) ; + rc = spi->DR; i++; } -- cgit v1.2.3 From 2e79aafb7081a5305ee875277d26734779ca6d2f Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Fri, 17 Sep 2010 03:49:14 -0400 Subject: Enable USB auto-reset in a hard fault. Redirect thread-mode execution to a fail routine which throbs the LED to indicate a hard fault. Because the fail routine runs in thread mode with interrupts on, USB auto-reset should now work. Test by executing some bogus instruction (e.g. *(volatile int*)0xf34fdaa = 0;) and check that the auto-reset continues to work. --- Makefile | 9 ++++--- libmaple/exc.c | 63 --------------------------------------------- libmaple/rules.mk | 11 +++++--- libmaple/util.c | 51 ++++++++++++++++++++++-------------- libmaple/util.h | 1 + support/make/build-rules.mk | 7 +++-- 6 files changed, 49 insertions(+), 93 deletions(-) delete mode 100644 libmaple/exc.c (limited to 'libmaple') diff --git a/Makefile b/Makefile index bc34f9e..4fd5ade 100644 --- a/Makefile +++ b/Makefile @@ -29,11 +29,12 @@ LIBMAPLE_PATH := $(SRCROOT)/libmaple SUPPORT_PATH := $(SRCROOT)/support # Useful variables -GLOBAL_CFLAGS := -Os -g -mcpu=cortex-m3 -mthumb -march=armv7-m -nostdlib \ - -ffunction-sections -fdata-sections -Wl,--gc-sections \ - -DBOARD_$(BOARD) -DMCU_$(MCU) +GLOBAL_CFLAGS := -Os -g -mcpu=cortex-m3 -mthumb -march=armv7-m -nostdlib \ + -ffunction-sections -fdata-sections -Wl,--gc-sections \ + -DBOARD_$(BOARD) -DMCU_$(MCU) GLOBAL_CXXFLAGS := -fno-rtti -fno-exceptions -Wall -DBOARD_$(BOARD) -DMCU_$(MCU) - +GLOBAL_ASFLAGS := -mcpu=cortex-m3 -march=armv7-m -mthumb -DBOARD_$(BOARD) \ + -DMCU_$(MCU) -x assembler-with-cpp LDDIR := $(SUPPORT_PATH)/ld LDFLAGS = -T$(LDDIR)/$(LDSCRIPT) -L$(LDDIR) \ diff --git a/libmaple/exc.c b/libmaple/exc.c deleted file mode 100644 index a5c67fa..0000000 --- a/libmaple/exc.c +++ /dev/null @@ -1,63 +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 libmaple exception handlers. If DEBUG_LEVEL > DEBUG_FAULT, then these - * exceptions will ASSERT fail and call into the default _fail() light - * blinking. - */ - -#include "util.h" - -void NMIException(void) { - ASSERT_FAULT(0); - while(1) - ; -} - -void HardFaultException(void) { - ASSERT_FAULT(0); - while(1) - ; -} - -void MemManageException(void) { - ASSERT_FAULT(0); - while(1) - ; -} - -void BusFaultException(void) { - ASSERT_FAULT(0); - while(1) - ; -} - -void UsageFaultException(void) { - ASSERT_FAULT(0); - while(1) - ; -} - diff --git a/libmaple/rules.mk b/libmaple/rules.mk index 8428277..cd50495 100644 --- a/libmaple/rules.mk +++ b/libmaple/rules.mk @@ -16,7 +16,6 @@ cSRCS_$(d) := systick.c \ timers.c \ adc.c \ syscalls.c \ - exc.c \ exti.c \ gpio.c \ nvic.c \ @@ -25,8 +24,8 @@ cSRCS_$(d) := systick.c \ rcc.c \ flash.c \ spi.c \ - fsmc.c \ - dac.c \ + fsmc.c \ + dac.c \ usb/usb.c \ usb/usb_callbacks.c \ usb/usb_hardware.c \ @@ -37,12 +36,16 @@ cSRCS_$(d) := systick.c \ usb/usb_lib/usb_mem.c \ usb/usb_lib/usb_regs.c +sSRCS_$(d) := exc.S + cFILES_$(d) := $(cSRCS_$(d):%=$(d)/%) +sFILES_$(d) := $(sSRCS_$(d):%=$(d)/%) -OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) +OBJS_$(d) := $(cFILES_$(d):%.c=$(BUILD_PATH)/%.o) $(sFILES_$(d):%.S=$(BUILD_PATH)/%.o) DEPS_$(d) := $(OBJS_$(d):%.o=%.d) $(OBJS_$(d)): TGT_CFLAGS := $(CFLAGS_$(d)) +$(OBJS_$(d)): TGT_ASFLAGS := TGT_BIN += $(OBJS_$(d)) diff --git a/libmaple/util.c b/libmaple/util.c index a747948..3325d2b 100644 --- a/libmaple/util.c +++ b/libmaple/util.c @@ -68,7 +68,7 @@ void _fail(const char* file, int line, const char* exp) { usart_putudec(ERROR_USART_NUM, line); usart_putc(ERROR_USART_NUM, '\n'); usart_putc(ERROR_USART_NUM, '\r'); - + /* Turn on the error LED */ gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); @@ -77,24 +77,35 @@ void _fail(const char* file, int line, const char* exp) { nvic_irq_enable(NVIC_INT_USBLP); /* Error fade */ - while (1) { - if (CC == TOP_CNT) { - slope = -1; - } else if (CC == 0) { - slope = 1; - } - - if (i == TOP_CNT) { - CC += slope; - i = 0; - } - - if (i < CC) { - gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 1); - } else { - gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 0); - } - i++; - } + throb(); +} + +void throb(void) { + int32 slope = 1; + uint32 CC = 0x0000; + uint32 TOP_CNT = 0x0200; + uint32 i = 0; + + gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); + /* Error fade */ + while (1) { + if (CC == TOP_CNT) { + slope = -1; + } else if (CC == 0) { + slope = 1; + } + + if (i == TOP_CNT) { + CC += slope; + i = 0; + } + + if (i < CC) { + gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 1); + } else { + gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 0); + } + i++; + } } diff --git a/libmaple/util.h b/libmaple/util.h index 63e305d..be5e430 100644 --- a/libmaple/util.h +++ b/libmaple/util.h @@ -66,6 +66,7 @@ extern "C"{ #endif void _fail(const char*, int, const char*); +void throb(void); #ifdef __cplusplus } // extern "C" diff --git a/support/make/build-rules.mk b/support/make/build-rules.mk index 3892af9..4dcf00f 100644 --- a/support/make/build-rules.mk +++ b/support/make/build-rules.mk @@ -3,7 +3,7 @@ CC := arm-none-eabi-gcc CXX := arm-none-eabi-g++ LD := arm-none-eabi-ld -v AR := arm-none-eabi-ar -AS := arm-none-eabi-as +AS := arm-none-eabi-gcc OBJCOPY := arm-none-eabi-objcopy DISAS := arm-none-eabi-objdump OBJDUMP := arm-none-eabi-objdump @@ -14,10 +14,10 @@ OPENOCD := openocd # Suppress annoying output unless V is set ifndef V SILENT_CC = @echo ' [CC] ' $(@:$(BUILD_PATH)/%.o=%.c); + SILENT_AS = @echo ' [AS] ' $(@:$(BUILD_PATH)/%.o=%.S); SILENT_CXX = @echo ' [CXX] ' $(@:$(BUILD_PATH)/%.o=%.cpp); SILENT_LD = @echo ' [LD] ' $(@F); SILENT_AR = @echo ' [AR] ' - SILENT_AS = @echo ' [AS] ' SILENT_OBJCOPY = @echo ' [OBJCOPY] ' $(@F); SILENT_DISAS = @echo ' [DISAS] ' $(@:$(BUILD_PATH)/%.bin=%).disas; SILENT_OBJDUMP = @echo ' [OBJDUMP] ' $(OBJDUMP); @@ -28,6 +28,7 @@ TGT_BIN := CFLAGS = $(GLOBAL_CFLAGS) $(TGT_CFLAGS) CXXFLAGS = $(GLOBAL_CXXFLAGS) $(TGT_CXXFLAGS) +ASFLAGS = $(GLOBAL_ASFLAGS) $(TGT_ASFLAGS) # General directory independent build rules, generate dependency information $(BUILD_PATH)/%.o: %.c @@ -36,3 +37,5 @@ $(BUILD_PATH)/%.o: %.c $(BUILD_PATH)/%.o: %.cpp $(SILENT_CXX) $(CXX) $(CFLAGS) $(CXXFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $< +$(BUILD_PATH)/%.o: %.S + $(SILENT_AS) $(AS) $(ASFLAGS) -MMD -MP -MF $(@:%.o=%.d) -MT $@ -o $@ -c $< -- cgit v1.2.3 From 0f82ae884f3ac2683db9fb4abd0d9be12bb83606 Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Fri, 17 Sep 2010 03:57:52 -0400 Subject: Forgot to add exc.S whoops. --- libmaple/exc.S | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 libmaple/exc.S (limited to 'libmaple') diff --git a/libmaple/exc.S b/libmaple/exc.S new file mode 100644 index 0000000..541a61a --- /dev/null +++ b/libmaple/exc.S @@ -0,0 +1,38 @@ +.text + +# On an exception, push a fake stack thread mode stack frame and redirect +# thread execution to a thread mode error handler + +# From RM008: +# The SP is decremented by eight words by the completion of the stack push. +# Figure 5-1 shows the contents of the stack after an exception pre-empts the +# current program flow. +# +# Old SP--> +# xPSR +# PC +# LR +# r12 +# r3 +# r2 +# r1 +# SP--> r0 + +.globl HardFaultException +.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 + bx lr @ Exception exit + + .align 4 + CPSR_MASK: .word 0x61000000 + EXC_RETURN: .word 0xFFFFFFF9 + TARGET_PC: .word throb + + -- cgit v1.2.3 From ff31b640dd7614faa29466ed02da5267c2a02225 Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Fri, 17 Sep 2010 04:27:08 -0400 Subject: Add MIT license on exc.S --- libmaple/exc.S | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'libmaple') diff --git a/libmaple/exc.S b/libmaple/exc.S index 541a61a..a9f6561 100644 --- a/libmaple/exc.S +++ b/libmaple/exc.S @@ -1,4 +1,26 @@ -.text +/* ***************************************************************************** + * 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. + * ****************************************************************************/ # On an exception, push a fake stack thread mode stack frame and redirect # thread execution to a thread mode error handler @@ -18,6 +40,7 @@ # r1 # SP--> r0 +.text .globl HardFaultException .thumb_func HardFaultException: -- cgit v1.2.3 From f2fd21628e79ac8e9289a1a8b8f7d11ad4797361 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Tue, 21 Sep 2010 17:21:36 -0400 Subject: minor bugfix to BIT definition --- libmaple/util.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libmaple') diff --git a/libmaple/util.h b/libmaple/util.h index be5e430..f5e7e88 100644 --- a/libmaple/util.h +++ b/libmaple/util.h @@ -34,7 +34,7 @@ #include "libmaple.h" -#define BIT(shift) (1 << (shift)) +#define BIT(shift) (1UL << (shift)) #define BIT_MASK_SHIFT(mask, shift) ((mask) << (shift)) /* Return bits m to n of x */ @@ -74,7 +74,7 @@ void throb(void); // Asserts for sanity checks, redefine DEBUG_LEVEL in libmaple.h to compile out -// these checks +// these checks #define DEBUG_NONE 0 #define DEBUG_FAULT 1 -- cgit v1.2.3 From 89cd6296ea10658c87b6dddf75a46308437dbb17 Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Wed, 22 Sep 2010 02:59:26 -0400 Subject: Fix improper interrupt clearing Interrupts should be cleared by writing to the interrupt clear-enable register (ICER). This commit fixes an improper read-modify-write on NVIC_ICER[n] that incorrectly cleared interrupt-enable bits on non-designated channels. --- libmaple/nvic.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'libmaple') diff --git a/libmaple/nvic.c b/libmaple/nvic.c index 60e7eac..b911e35 100644 --- a/libmaple/nvic.c +++ b/libmaple/nvic.c @@ -42,13 +42,8 @@ void nvic_set_vector_table(uint32 addr, uint32 offset) { * @param n interrupt number */ void nvic_irq_enable(uint32 n) { - if (n < 32) { - REG_SET_BIT(NVIC_ISER0, n); - } else if(n < 64) { - REG_SET_BIT(NVIC_ISER1, n - 32); - } else { - REG_SET_BIT(NVIC_ISER2, n - 64); - } + uint32 *iser = &((uint32*)NVIC_ISER0)[(n/32)]; + __write(iser, BIT(n % 32)); } /** @@ -56,13 +51,8 @@ void nvic_irq_enable(uint32 n) { * @param n interrupt number */ void nvic_irq_disable(uint32 n) { - if (n < 32) { - REG_SET_BIT(NVIC_ICER0, n); - } else if(n < 64) { - REG_SET_BIT(NVIC_ICER1, n - 32); - } else { - REG_SET_BIT(NVIC_ICER2, n - 64); - } + uint32 *icer = &((uint32*)NVIC_ICER0)[(n/32)]; + __write(icer, BIT(n % 32)); } void nvic_irq_disable_all(void) { -- cgit v1.2.3 From c13e850abe053edaa1aad6ef7b928c6bf9288cb3 Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Wed, 22 Sep 2010 03:17:45 -0400 Subject: Enable external interrupts on all Maple GPIOs. Extend the wirish attachInterrupt() and detachInterrupt() interface to work with all GPIOs. Note: The STM32 external interrupt lines are multiplexed between GPIO ports. While any GPIO can be used as an external interrupt, not all of them can be used at the same time. Each EXTI[n] line selects between PA[n], PB[n], PC[n], etc. For example, line EXTI5 can be used with STM32 pins PA5, PB5, or PC5, but not all at the same time. See table: EXTI Line Maple Pin STM32 Pin 0 D2 PA0 0 D27 PB0 0 D15 PC0 1 D3 PA1 1 D28 PB1 1 D16 PC1 2 D1 PA2 2 D17 PC2 2 D25 PD2 3 D0 PA3 3 D18 PC3 4 D10 PA4 4 D19 PC4 5 D13 PA5 5 D4 PB5 5 D20 PC5 6 D12 PA6 6 D5 PB6 6 D35 PC6 7 D11 PA7 7 D9 PB7 7 D36 PC7 8 D6 PA8 8 D14 PB8 8 D37 PC8 9 D7 PA9 9 D24 PB9 9 D38 PC9 (BUT) 10 D8 PA10 10 D29 PB10 10 D26 PC10 11 D30 PB11 12 D31 PB12 13 D32 PB13 13 D21 PC13 14 D33 PB14 14 D22 PC14 15 D34 PB15 15 D23 PC15 --- libmaple/exti.c | 234 ++++++++++++++++------------------------------ libmaple/exti.h | 13 ++- libmaple/libmaple_types.h | 4 + libmaple/nvic.h | 37 +++++--- wirish/boards.h | 102 ++++++++------------ wirish/ext_interrupts.c | 36 +++---- wirish/ext_interrupts.h | 11 +-- 7 files changed, 173 insertions(+), 264 deletions(-) (limited to 'libmaple') diff --git a/libmaple/exti.c b/libmaple/exti.c index 5575906..8a54457 100644 --- a/libmaple/exti.c +++ b/libmaple/exti.c @@ -33,10 +33,32 @@ #include "exti.h" #include "nvic.h" -volatile static voidFuncPtr exti_handlers[NR_EXTI_CHANNELS]; +typedef struct ExtIChannel { + void (*handler)(void); + uint32 irq_line; +} ExtIChannel; + +static ExtIChannel exti_channels[] = { + { .handler = NULL, .irq_line = NVIC_EXTI0 }, // EXTI0 + { .handler = NULL, .irq_line = NVIC_EXTI1 }, // EXTI1 + { .handler = NULL, .irq_line = NVIC_EXTI2 }, // EXTI2 + { .handler = NULL, .irq_line = NVIC_EXTI3 }, // EXTI3 + { .handler = NULL, .irq_line = NVIC_EXTI4 }, // EXTI4 + { .handler = NULL, .irq_line = NVIC_EXTI9_5 }, // EXTI5 + { .handler = NULL, .irq_line = NVIC_EXTI9_5 }, // EXTI6 + { .handler = NULL, .irq_line = NVIC_EXTI9_5 }, // EXTI7 + { .handler = NULL, .irq_line = NVIC_EXTI9_5 }, // EXTI8 + { .handler = NULL, .irq_line = NVIC_EXTI9_5 }, // EXTI9 + { .handler = NULL, .irq_line = NVIC_EXTI15_10 }, // EXTI10 + { .handler = NULL, .irq_line = NVIC_EXTI15_10 }, // EXTI11 + { .handler = NULL, .irq_line = NVIC_EXTI15_10 }, // EXTI12 + { .handler = NULL, .irq_line = NVIC_EXTI15_10 }, // EXTI13 + { .handler = NULL, .irq_line = NVIC_EXTI15_10 }, // EXTI14 + { .handler = NULL, .irq_line = NVIC_EXTI15_10 }, // EXTI15 +}; static inline void clear_pending(int bit) { - REG_SET(EXTI_PR, BIT(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. */ @@ -44,61 +66,39 @@ static inline void clear_pending(int bit) { asm volatile("nop"); } +static inline void dispatch_handler(uint32 channel) { + ASSERT(exti_channels[channel].handler); + if (exti_channels[channel].handler) { + (exti_channels[channel].handler)(); + } +} + /* For EXTI0 through EXTI4, only one handler * is associated with each channel, so we * don't have to keep track of which channel * we came from */ void EXTI0_IRQHandler(void) { - ASSERT(exti_handlers[EXTI0]); - if (exti_handlers[EXTI0]) { - exti_handlers[EXTI0](); - } - - /* Clear pending bit*/ + dispatch_handler(EXTI0); clear_pending(EXTI0); } void EXTI1_IRQHandler(void) { - ASSERT(exti_handlers[EXTI1]); - /* Call registered handler */ - if (exti_handlers[EXTI1]) { - exti_handlers[EXTI1](); - } - - /* Clear pending bit*/ + dispatch_handler(EXTI1); clear_pending(EXTI1); } void EXTI2_IRQHandler(void) { - ASSERT(exti_handlers[EXTI2]); - /* Call registered handler */ - if (exti_handlers[EXTI2]) { - exti_handlers[EXTI2](); - } - - /* Clear pending bit*/ + dispatch_handler(EXTI2); clear_pending(EXTI2); } void EXTI3_IRQHandler(void) { - ASSERT(exti_handlers[EXTI3]); - /* Call registered handler */ - if (exti_handlers[EXTI3]) { - exti_handlers[EXTI3](); - } - - /* Clear pending bit*/ + dispatch_handler(EXTI3); clear_pending(EXTI3); } void EXTI4_IRQHandler(void) { - ASSERT(exti_handlers[EXTI4]); - /* Call registered handler */ - if (exti_handlers[EXTI4]) { - exti_handlers[EXTI4](); - } - - /* Clear pending bit*/ + dispatch_handler(EXTI4); clear_pending(EXTI4); } @@ -112,8 +112,7 @@ void EXTI9_5_IRQHandler(void) { /* Dispatch every handler if the pending bit is set */ for (i = 0; i < 5; i++) { if (pending & 0x1) { - ASSERT(exti_handlers[EXTI5 + i]); - exti_handlers[EXTI5 + i](); + dispatch_handler(EXTI5 + i); clear_pending(EXTI5 + i); } pending >>= 1; @@ -130,8 +129,7 @@ void EXTI15_10_IRQHandler(void) { /* Dispatch every handler if the pending bit is set */ for (i = 0; i < 6; i++) { if (pending & 0x1) { - ASSERT(exti_handlers[EXTI10 + i]); - exti_handlers[EXTI10 + i](); + dispatch_handler(EXTI10 + i); clear_pending(EXTI10 + i); } pending >>= 1; @@ -139,147 +137,73 @@ void EXTI15_10_IRQHandler(void) { } -void exti_attach_interrupt(uint8 channel, uint8 port, voidFuncPtr handler, uint8 mode) { - ASSERT(channel < NR_EXTI_CHANNELS); - ASSERT(port < NR_EXTI_PORTS); - ASSERT(mode < NR_EXTI_MODES); - ASSERT(EXTI0 == 0); - ASSERT(handler); +/** + * @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 + */ +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); - /* Map port to the correct EXTI channel */ - switch (channel) { - case EXTI0: - case EXTI1: - case EXTI2: - case EXTI3: - REG_SET_MASK(AFIO_EXTICR1, BIT_MASK_SHIFT(port, channel*4)); - break; - - case EXTI4: - case EXTI5: - case EXTI6: - case EXTI7: - REG_SET_MASK(AFIO_EXTICR2, BIT_MASK_SHIFT(port, (channel-4)*4)); - break; - - case EXTI8: - case EXTI9: - case EXTI10: - case EXTI11: - REG_SET_MASK(AFIO_EXTICR3, BIT_MASK_SHIFT(port, (channel-8)*4)); - break; + uint32 channel = pin; - case EXTI12: - case EXTI13: - case EXTI14: - case EXTI15: - REG_SET_MASK(AFIO_EXTICR4, BIT_MASK_SHIFT(port, (channel-12)*4)); - break; - } + /* map port to channel */ + __write(afio_regs[pin/4], (port << ((pin % 4) * 4))); /* Unmask appropriate interrupt line */ - REG_SET_BIT(EXTI_IMR, channel); + __set_bits(EXTI_IMR, BIT(channel)); /* Set trigger mode */ switch (mode) { case EXTI_RISING: - REG_SET_BIT(EXTI_RTSR, channel); + __set_bits(EXTI_RTSR, BIT(channel)); break; case EXTI_FALLING: - REG_SET_BIT(EXTI_FTSR, channel); + __set_bits(EXTI_FTSR, BIT(channel)); break; case EXTI_RISING_FALLING: - REG_SET_BIT(EXTI_RTSR, channel); - REG_SET_BIT(EXTI_FTSR, channel); + __set_bits(EXTI_RTSR, BIT(channel)); + __set_bits(EXTI_FTSR, BIT(channel)); break; } /* Configure the enable interrupt bits for the NVIC */ - switch (channel) { - case EXTI0: - case EXTI1: - case EXTI2: - case EXTI3: - case EXTI4: - REG_SET(NVIC_ISER0, BIT(channel + 6)); - break; - - /* EXTI5-9 map to the same isr */ - case EXTI5: - case EXTI6: - case EXTI7: - case EXTI8: - case EXTI9: - REG_SET(NVIC_ISER0, BIT(23)); - break; - - /* EXTI10-15 map to the same isr */ - case EXTI10: - case EXTI11: - case EXTI12: - case EXTI13: - case EXTI14: - case EXTI15: - REG_SET(NVIC_ISER1, BIT(8)); - break; - } + nvic_irq_enable(exti_channels[channel].irq_line); /* Register the handler */ - exti_handlers[channel] = handler; + exti_channels[channel].handler = handler; } -void exti_detach_interrupt(uint8 channel) { +/** + * @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); - /* Is this interrupt actually on? */ - ASSERT((REG_GET(EXTI_IMR) >> channel) & 0x01); - - /* Clear EXTI_IMR line */ - REG_CLEAR_BIT(EXTI_IMR, channel); - - /* Clear triggers */ - REG_CLEAR_BIT(EXTI_FTSR, channel); - REG_CLEAR_BIT(EXTI_RTSR, channel); - - /* Turn off the associated interrupt */ - switch (channel) { - case EXTI0: - case EXTI1: - case EXTI2: - case EXTI3: - case EXTI4: - REG_SET(NVIC_ICER0, BIT(channel + 6)); - break; - case EXTI5: - case EXTI6: - case EXTI7: - case EXTI8: - case EXTI9: - /* Are there any other channels enabled? - * If so, don't disable the interrupt handler */ - if (GET_BITS(REG_GET(EXTI_IMR), 5, 9) == 0) { - REG_SET(NVIC_ICER0, BIT(23)); - } - break; - case EXTI10: - case EXTI11: - case EXTI12: - case EXTI13: - case EXTI14: - case EXTI15: - /* Are there any other channels enabled? - * If so, don't disable the interrupt handler */ - if (GET_BITS(REG_GET(EXTI_IMR), 10, 15) == 0) { - REG_SET(NVIC_ICER1, BIT(8)); - } - break; - } - /* Clear handler function pointer */ - exti_handlers[channel] = 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); + + exti_channels[channel].handler = NULL; } diff --git a/libmaple/exti.h b/libmaple/exti.h index 2832e24..97cb4aa 100644 --- a/libmaple/exti.h +++ b/libmaple/exti.h @@ -100,6 +100,10 @@ #define NR_EXTI_CHANNELS 16 #define NR_EXTI_PORTS NR_GPIO_PORTS // board specific +#define EXTI_RISING 0 +#define EXTI_FALLING 1 +#define EXTI_RISING_FALLING 2 + #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 @@ -113,10 +117,6 @@ #define AFIO_EXTICR3 (AFIO_EVCR + 0x10) #define AFIO_EXTICR4 (AFIO_EVCR + 0x14) -#define EXTI_RISING 0 -#define EXTI_FALLING 1 -#define EXTI_RISING_FALLING 2 - #define EXTI0 0 #define EXTI1 1 #define EXTI2 2 @@ -142,13 +142,12 @@ #define EXTI_CONFIG_PORTF 5 // Native only #define EXTI_CONFIG_PORTG 6 // Native only - #ifdef __cplusplus extern "C"{ #endif -void exti_attach_interrupt(uint8, uint8, voidFuncPtr, uint8); -void exti_detach_interrupt(uint8); +void exti_attach_interrupt(uint32, uint32, voidFuncPtr, uint32); +void exti_detach_interrupt(uint32); #ifdef __cplusplus } // extern "C" diff --git a/libmaple/libmaple_types.h b/libmaple/libmaple_types.h index d49f95a..da3c241 100644 --- a/libmaple/libmaple_types.h +++ b/libmaple/libmaple_types.h @@ -45,5 +45,9 @@ typedef void (*voidFuncPtr)(void); #define __io volatile +#ifndef NULL +#define NULL 0 +#endif + #endif diff --git a/libmaple/nvic.h b/libmaple/nvic.h index 3286357..ab56f0e 100644 --- a/libmaple/nvic.h +++ b/libmaple/nvic.h @@ -31,8 +31,6 @@ #define NVIC_INT_USBHP 19 #define NVIC_INT_USBLP 20 -#define NVIC_EXTI1_OFFSET (NVIC_ISER0 + 0x07) -#define NVIC_EXTI9_5_OFFSET (NVIC_ISER0 + 0x17) /* NVIC Interrupt Enable registers */ #define NVIC_ISER0 0xE000E100 @@ -57,19 +55,28 @@ extern "C"{ #endif enum { - NVIC_TIMER1 = 27, - NVIC_TIMER2 = 28, - NVIC_TIMER3 = 29, - NVIC_TIMER4 = 30, - NVIC_TIMER5 = 50, // high density only (Maple Native) - NVIC_TIMER6 = 54, // high density only (Maple Native) - NVIC_TIMER7 = 55, // high density only (Maple Native) - NVIC_TIMER8 = 46, // high density only (Maple Native) - NVIC_USART1 = 37, - NVIC_USART2 = 38, - NVIC_USART3 = 39, - NVIC_USART4 = 52, // high density only (Maple Native) - NVIC_USART5 = 53, // high density only (Maple Native) + NVIC_TIMER1 = 27, + NVIC_TIMER2 = 28, + NVIC_TIMER3 = 29, + NVIC_TIMER4 = 30, + NVIC_TIMER5 = 50, // high density only (Maple Native) + NVIC_TIMER6 = 54, // high density only (Maple Native) + NVIC_TIMER7 = 55, // high density only (Maple Native) + NVIC_TIMER8 = 46, // high density only (Maple Native) + + NVIC_USART1 = 37, + NVIC_USART2 = 38, + NVIC_USART3 = 39, + NVIC_USART4 = 52, // high density only (Maple Native) + NVIC_USART5 = 53, // high density only (Maple Native) + + NVIC_EXTI0 = 6, + NVIC_EXTI1 = 7, + NVIC_EXTI2 = 8, + NVIC_EXTI3 = 9, + NVIC_EXTI4 = 10, + NVIC_EXTI9_5 = 23, + NVIC_EXTI15_10 = 40, }; diff --git a/wirish/boards.h b/wirish/boards.h index 03d0b0e..0e0d159 100644 --- a/wirish/boards.h +++ b/wirish/boards.h @@ -64,13 +64,9 @@ typedef struct PinMapping { uint32 pin; uint32 adc; TimerCCR timer_channel; + uint32 exti_port; } PinMapping; -typedef struct ExtiInfo { - uint8 channel; - uint8 port; -} ExtiInfo; - // LeafLabs Maple rev3, rev4 #ifdef BOARD_maple @@ -78,65 +74,47 @@ typedef struct ExtiInfo { #define MAPLE_RELOAD_VAL 71999 /* takes a cycle to reload */ static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { - {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, // D0/PA3 - {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, // D1/PA2 - {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, // D2/PA0 - {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, // D3/PA1 - {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, // D4/PB5 - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, // D5/PB6 - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, // D6/PA8 - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, // D7/PA9 - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, // D8/PA10 - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, // D9/PB7 - {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, // D10/PA4 - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, // D11/PA7 - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, // D12/PA6 - {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, // D13/PA5 - {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, // D14/PB8 + {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA}, // D0/PA3 + {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA}, // D1/PA2 + {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA}, // D2/PA0 + {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA}, // D3/PA1 + {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, // D4/PB5 + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB}, // D5/PB6 + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA}, // D6/PA8 + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA}, // D7/PA9 + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA}, // D8/PA10 + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB}, // D9/PB7 + {GPIOA_BASE, 4, ADC4, TIMER_INVALID, EXTI_CONFIG_PORTA}, // D10/PA4 + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA}, // D11/PA7 + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA}, // D12/PA6 + {GPIOA_BASE, 5, ADC5, TIMER_INVALID, EXTI_CONFIG_PORTA}, // D13/PA5 + {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB}, // D14/PB8 /* Little header */ - {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, // D15/PC0 - {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, // D16/PC1 - {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, // D17/PC2 - {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, // D18/PC3 - {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, // D19/PC4 - {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, // D20/PC5 + {GPIOC_BASE, 0, ADC10, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D15/PC0 + {GPIOC_BASE, 1, ADC11, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D16/PC1 + {GPIOC_BASE, 2, ADC12, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D17/PC2 + {GPIOC_BASE, 3, ADC13, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D18/PC3 + {GPIOC_BASE, 4, ADC14, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D19/PC4 + {GPIOC_BASE, 5, ADC15, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D20/PC5 /* External header */ - {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D21/PC13 - {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D22/PC14 - {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D23/PC15 - {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, // D24/PB9 - {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, // D25/PD2 - {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D26/PC10 - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, // D27/PB0 - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, // D28/PB1 - {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, // D29/PB10 - {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, // D30/PB11 - {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, // D31/PB12 - {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, // D32/PB13 - {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, // D33/PB14 - {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, // D34/PB15 - {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, // D35/PC6 - {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, // D36/PC7 - {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, // D37/PC8 - {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} // D38/PC9 (BUT) - }; - - static __attribute__ ((unused)) ExtiInfo PIN_TO_EXTI_CHANNEL[NR_GPIO_PINS] = - { - {EXTI3, EXTI_CONFIG_PORTA}, // D0/PA3 - {EXTI2, EXTI_CONFIG_PORTA}, // D1/PA2 - {EXTI0, EXTI_CONFIG_PORTA}, // D2/PA0 - {EXTI1, EXTI_CONFIG_PORTA}, // D3/PA1 - {EXTI5, EXTI_CONFIG_PORTB}, // D4/PB5 - {EXTI6, EXTI_CONFIG_PORTB}, // D5/PB6 - {EXTI8, EXTI_CONFIG_PORTA}, // D6/PA8 - {EXTI9, EXTI_CONFIG_PORTA}, // D7/PA9 - {EXTI10, EXTI_CONFIG_PORTA}, // D8/PA10 - {EXTI7, EXTI_CONFIG_PORTB}, // D9/PB7 - {EXTI4, EXTI_CONFIG_PORTA}, // D10/PA4 - {EXTI7, EXTI_CONFIG_PORTA}, // D11/PA7 - {EXTI6, EXTI_CONFIG_PORTA}, // D12/PA6 - {EXTI5, EXTI_CONFIG_PORTA}, // D13/PA5 + {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D21/PC13 + {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D22/PC14 + {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D23/PC15 + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB}, // D24/PB9 + {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTD}, // D25/PD2 + {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D26/PC10 + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB}, // D27/PB0 + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB}, // D28/PB1 + {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, // D29/PB10 + {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, // D30/PB11 + {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, // D31/PB12 + {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, // D32/PB13 + {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, // D33/PB14 + {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, // D34/PB15 + {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D35/PC6 + {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D36/PC7 + {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, // D37/PC8 + {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC} // D38/PC9 (BUT) }; #endif diff --git a/wirish/ext_interrupts.c b/wirish/ext_interrupts.c index 6ba1d05..5009d75 100644 --- a/wirish/ext_interrupts.c +++ b/wirish/ext_interrupts.c @@ -36,22 +36,21 @@ * @brief Attach an interrupt handler to be triggered on a given * transition on the pin. Runs in interrupt context * - * @param[in] pin Maple pin number - * @param[in] handler Function to run upon external interrupt trigger. - * @param[in] mode Type of transition to trigger on, eg falling, rising, etc. + * @param pin Maple pin number + * @param handler Function to run upon external interrupt trigger. + * @param mode Type of transition to trigger on, eg falling, rising, etc. * * @sideeffect Registers a handler */ -int attachInterrupt(uint8 pin, voidFuncPtr handler, uint32 mode) { +void attachInterrupt(uint8 pin, voidFuncPtr handler, uint32 mode) { uint8 outMode; /* Parameter checking */ if (pin >= NR_GPIO_PINS) { - return EXT_INTERRUPT_INVALID_PIN; + return; } if (!handler) { - ASSERT(0); - return EXT_INTERRUPT_INVALID_FUNCTION; + return; } switch (mode) { @@ -65,22 +64,27 @@ int attachInterrupt(uint8 pin, voidFuncPtr handler, uint32 mode) { outMode = EXTI_RISING_FALLING; break; default: - ASSERT(0); - return EXT_INTERRUPT_INVALID_MODE;; + return; } - exti_attach_interrupt(PIN_TO_EXTI_CHANNEL[pin].channel, - PIN_TO_EXTI_CHANNEL[pin].port, - handler, mode); + exti_attach_interrupt(PIN_MAP[pin].exti_port, + PIN_MAP[pin].pin, + handler, + mode); - return 0; + return; } -int detachInterrupt(uint8 pin) { +/** + * @brief Disable an external interrupt + * @param pin maple pin number + * @sideeffect unregisters external interrupt handler + */ +void detachInterrupt(uint8 pin) { if (!(pin < NR_GPIO_PINS)) { - return EXT_INTERRUPT_INVALID_PIN; + return; } - exti_detach_interrupt(PIN_TO_EXTI_CHANNEL[pin].channel); + exti_detach_interrupt(PIN_MAP[pin].pin); } diff --git a/wirish/ext_interrupts.h b/wirish/ext_interrupts.h index 7449685..62f31bb 100644 --- a/wirish/ext_interrupts.h +++ b/wirish/ext_interrupts.h @@ -37,19 +37,12 @@ enum { CHANGE }; - -enum { - EXT_INTERRUPT_INVALID_PIN = (-1), - EXT_INTERRUPT_INVALID_FUNCTION = (-2), - EXT_INTERRUPT_INVALID_MODE = (-3), -}; - #ifdef __cplusplus extern "C"{ #endif -int attachInterrupt(uint8 pin, voidFuncPtr, uint32 mode); -int detachInterrupt(uint8 pin); +void attachInterrupt(uint8 pin, voidFuncPtr, uint32 mode); +void detachInterrupt(uint8 pin); #ifdef __cplusplus } -- cgit v1.2.3 From 753f89de354eff212d84f3f2aff41146865da342 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Mon, 27 Sep 2010 00:40:44 -0400 Subject: whitespace cleanups --- libmaple/adc.c | 26 +++-- libmaple/adc.h | 17 ++- libmaple/dac.c | 38 +++---- libmaple/dac.h | 47 ++++---- libmaple/exti.c | 15 ++- libmaple/exti.h | 77 +++++++------ libmaple/flash.c | 22 ++-- libmaple/flash.h | 4 +- libmaple/fsmc.c | 56 +++++----- libmaple/fsmc.h | 14 +-- libmaple/gpio.c | 61 +++++----- libmaple/gpio.h | 46 ++++---- libmaple/libmaple.h | 4 +- libmaple/libmaple_types.h | 4 +- libmaple/nvic.c | 25 ++--- libmaple/nvic.h | 48 ++++---- libmaple/rcc.c | 190 ++++++++++++++++--------------- libmaple/rcc.h | 68 +++++------ libmaple/ring_buffer.h | 24 ++-- libmaple/spi.c | 145 ++++++++++++------------ libmaple/spi.h | 63 +++++------ libmaple/syscalls.c | 54 +++------ libmaple/systick.c | 30 ++--- libmaple/systick.h | 10 +- libmaple/timers.c | 279 ++++++++++++++++++++++++---------------------- libmaple/timers.h | 60 +++++----- libmaple/usart.c | 89 ++++++++------- libmaple/usart.h | 34 +++--- libmaple/usb/README | 116 +++++++++++-------- libmaple/util.c | 72 ++++++------ libmaple/util.h | 59 +++++----- notes/fsmc.txt | 17 +-- 32 files changed, 914 insertions(+), 900 deletions(-) (limited to 'libmaple') diff --git a/libmaple/adc.c b/libmaple/adc.c index 021758c..9b21b49 100644 --- a/libmaple/adc.c +++ b/libmaple/adc.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,12 +20,12 @@ * 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 adc.c + * @file adc.c * - * @brief Analog to digital converter routines + * @brief Analog to digital converter routines */ #include "libmaple.h" @@ -63,23 +63,25 @@ * At 55.5 cycles/sample, the external input impedance < 50kOhms*/ void adc_init(void) { - rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6); - rcc_clk_enable(RCC_ADC1); - rcc_reset_dev(RCC_ADC1); + rcc_set_prescaler(RCC_PRESCALER_ADC, RCC_ADCPRE_PCLK_DIV_6); + rcc_clk_enable(RCC_ADC1); + rcc_reset_dev(RCC_ADC1); ADC_CR1 = 0; - ADC_CR2 = CR2_EXTSEL_SWSTART | CR2_EXTTRIG; // Software triggers conversions + /* Software triggers conversions */ + ADC_CR2 = CR2_EXTSEL_SWSTART | CR2_EXTTRIG; ADC_SQR1 = 0; - /* Up the sample conversion time to 55.5 cycles/sec, see note above */ - /* TODO: fix magic numbers */ + /* Up the sample conversion time to 55.5 cycles/sec, see note + above */ + /* TODO: fix magic numbers */ ADC_SMPR1 = 0xB6DB6D; ADC_SMPR2 = 0x2DB6DB6D; - /* Enable the ADC */ + /* Enable the ADC */ CR2_ADON_BIT = 1; - /* Reset the calibration registers and then perform a reset */ + /* Reset the calibration registers and then perform a reset */ CR2_RSTCAL_BIT = 1; while(CR2_RSTCAL_BIT) ; diff --git a/libmaple/adc.h b/libmaple/adc.h index f98a5f2..f41044f 100644 --- a/libmaple/adc.h +++ b/libmaple/adc.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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 adc.h @@ -62,13 +62,12 @@ extern "C"{ #define CR2_EXTTRIG (BIT(20)) /* Bit banded bits */ -#define CR2_ADON_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 0)) -#define CR2_CAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 2)) -#define CR2_RSTCAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 3)) -#define CR2_SWSTART_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8 + 2, 6)) -#define SR_EOC_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0, 1)) - -// NR_ANALOG_PINS is board specific +#define CR2_ADON_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 0)) +#define CR2_CAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 2)) +#define CR2_RSTCAL_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8, 3)) +#define CR2_SWSTART_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0x8 + 2, 6)) +#define SR_EOC_BIT *(volatile uint32*)(BITBAND_PERI(ADC1_BASE+0, 1)) +/* (NR_ANALOG_PINS is board specific) */ /* Initialize ADC1 to do one-shot conversions */ void adc_init(void); diff --git a/libmaple/dac.c b/libmaple/dac.c index ffc34f8..4c00edb 100644 --- a/libmaple/dac.c +++ b/libmaple/dac.c @@ -1,5 +1,4 @@ - -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Bryan Newbold. @@ -21,47 +20,44 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * ****************************************************************************/ + *****************************************************************************/ #include "libmaple.h" #include "rcc.h" #include "gpio.h" #include "dac.h" -// Only one, so global to this file +/* Only one, so global to this file */ DAC_Map *dac = (DAC_Map*)(DAC_BASE); -// This numbering follows the registers (1-indexed) +/* This numbering follows the registers (1-indexed) */ #define DAC_CHA 1 #define DAC_CHB 2 -// Sets up the DAC peripheral +/* Sets up the DAC peripheral */ void dac_init(void) { - - // First turn on the clock + /* First turn on the clock */ rcc_clk_enable(RCC_DAC); - // Then setup ANALOG mode on PA4 and PA5 + /* Then setup ANALOG mode on PA4 and PA5 */ gpio_set_mode(GPIOA_BASE, 4, CNF_INPUT_ANALOG); gpio_set_mode(GPIOA_BASE, 5, CNF_INPUT_ANALOG); - // Then do register stuff. - // Default does no triggering, and buffered output, so all good. + /* Then do register stuff. Default does no triggering, and + * buffered output, so all good. */ dac->CR |= DAC_CR_EN1; dac->CR |= DAC_CR_EN2; - } void dac_write(uint8 chan, uint16 val) { - switch(chan) { - case DAC_CHA: - dac->DHR12R1 = 0x0FFF & val; - break; - case DAC_CHB: - dac->DHR12R2 = 0x0FFF & val; - break; - default: - ASSERT(0); // Shouldn't get here + case DAC_CHA: + dac->DHR12R1 = 0x0FFF & val; + break; + case DAC_CHB: + dac->DHR12R2 = 0x0FFF & val; + break; + default: + ASSERT(0); // can't happen } } diff --git a/libmaple/dac.h b/libmaple/dac.h index de1fd3f..17b67b7 100644 --- a/libmaple/dac.h +++ b/libmaple/dac.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Bryan Newbold. @@ -20,9 +20,9 @@ * 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. - * ****************************************************************************/ + *****************************************************************************/ -/* +/* * See ../notes/dac.txt for more info */ @@ -36,19 +36,19 @@ extern "C"{ #define DAC_BASE 0x40007400 typedef struct { - volatile uint32 CR; - volatile uint32 SWTRIGR; - volatile uint32 DHR12R1; - volatile uint32 DHR12L1; - volatile uint32 DHR8R1; - volatile uint32 DHR12R2; - volatile uint32 DHR12L2; - volatile uint32 DHR8R2; - volatile uint32 DHR12RD; - volatile uint32 DHR12LD; - volatile uint32 DHR8RD; - volatile uint32 DOR1; - volatile uint32 DOR2; + volatile uint32 CR; + volatile uint32 SWTRIGR; + volatile uint32 DHR12R1; + volatile uint32 DHR12L1; + volatile uint32 DHR8R1; + volatile uint32 DHR12R2; + volatile uint32 DHR12L2; + volatile uint32 DHR8R2; + volatile uint32 DHR12RD; + volatile uint32 DHR12LD; + volatile uint32 DHR8RD; + volatile uint32 DOR1; + volatile uint32 DOR2; } DAC_Map; @@ -73,29 +73,28 @@ typedef struct { #define DAC_DHR12R1_DACC1DHR 0x00000FFF -#define DAC_DHR12L1_DACC1DHR 0x0000FFF0 +#define DAC_DHR12L1_DACC1DHR 0x0000FFF0 -#define DAC_DHR8R1_DACC1DHR 0x000000FF +#define DAC_DHR8R1_DACC1DHR 0x000000FF -#define DAC_DHR12R2_DACC2DHR 0x00000FFF +#define DAC_DHR12R2_DACC2DHR 0x00000FFF #define DAC_DHR12L2_DACC2DHR 0x0000FFF0 -#define DAC_DHR8R2_DACC2DHR 0x000000FF +#define DAC_DHR8R2_DACC2DHR 0x000000FF #define DAC_DHR12RD_DACC1DHR 0x00000FFF #define DAC_DHR12RD_DACC2DHR 0x0FFF0000 -#define DAC_DHR12LD_DACC1DHR 0x0000FFF0 +#define DAC_DHR12LD_DACC1DHR 0x0000FFF0 #define DAC_DHR12LD_DACC2DHR 0xFFF00000 #define DAC_DHR8RD_DACC1DHR 0x000000FF #define DAC_DHR8RD_DACC2DHR 0x0000FF00 -#define DAC_DOR1 0x00000FFF - -#define DAC_DOR2 0x00000FFF +#define DAC_DOR1 0x00000FFF +#define DAC_DOR2 0x00000FFF void dac_init(void); void dac_write(uint8 chan, uint16 val); diff --git a/libmaple/exti.c b/libmaple/exti.c index 8a54457..acd7c94 100644 --- a/libmaple/exti.c +++ b/libmaple/exti.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,13 +20,12 @@ * 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 exti.c + * @file exti.c * - * @brief External interrupt control routines + * @brief External interrupt control routines */ #include "libmaple.h" @@ -145,9 +144,9 @@ void EXTI15_10_IRQHandler(void) { * @param mode type of transition to trigger on */ void exti_attach_interrupt(uint32 port, - uint32 pin, - voidFuncPtr handler, - uint32 mode) { + uint32 pin, + voidFuncPtr handler, + uint32 mode) { static uint32 afio_regs[] = { AFIO_EXTICR1, // EXT0-3 AFIO_EXTICR2, // EXT4-7 diff --git a/libmaple/exti.h b/libmaple/exti.h index 97cb4aa..89cd986 100644 --- a/libmaple/exti.h +++ b/libmaple/exti.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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. - * ****************************************************************************/ + *****************************************************************************/ /** @@ -34,47 +34,54 @@ /* 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. + * 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 + * + * 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. + * 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." + * 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 + * 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 + * 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 + * 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 + * 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 + * 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 @@ -104,12 +111,12 @@ #define EXTI_FALLING 1 #define EXTI_RISING_FALLING 2 -#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 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) diff --git a/libmaple/flash.c b/libmaple/flash.c index 828f938..1d7bfa6 100644 --- a/libmaple/flash.c +++ b/libmaple/flash.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,13 +20,12 @@ * 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 flash peripheral management functions + * @brief flash peripheral management functions */ - #include "libmaple.h" #include "flash.h" @@ -48,23 +47,22 @@ * @brief turn on the hardware prefetcher */ void flash_enable_prefetch(void) { - uint32 val = FLASH_READ_ACR(); + uint32 val = FLASH_READ_ACR(); - val |= ACR_PRFTBE_ENABLE; + val |= ACR_PRFTBE_ENABLE; - FLASH_WRITE_ACR(val); + FLASH_WRITE_ACR(val); } - /** * @brief set flash wait states * @param number of wait states */ void flash_set_latency(uint32 wait_states) { - uint32 val = FLASH_READ_ACR(); + uint32 val = FLASH_READ_ACR(); - val &= ~ACR_LATENCY; - val |= wait_states; + val &= ~ACR_LATENCY; + val |= wait_states; - FLASH_WRITE_ACR(val); + FLASH_WRITE_ACR(val); } diff --git a/libmaple/flash.h b/libmaple/flash.h index a1ae0a4..54bda0e 100644 --- a/libmaple/flash.h +++ b/libmaple/flash.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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. - * ****************************************************************************/ + *****************************************************************************/ /** diff --git a/libmaple/fsmc.c b/libmaple/fsmc.c index 502b7b4..301a90d 100644 --- a/libmaple/fsmc.c +++ b/libmaple/fsmc.c @@ -1,5 +1,4 @@ - -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Bryan Newbold. @@ -21,26 +20,27 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * ****************************************************************************/ + *****************************************************************************/ #include "libmaple.h" #include "rcc.h" #include "gpio.h" #include "fsmc.h" -// These values determined for a particular SRAM chip by following the -// calculations in the ST FSMC application note. +/* These values determined for a particular SRAM chip by following the + * calculations in the ST FSMC application note. */ #define FSMC_ADDSET 0x0 #define FSMC_DATAST 0x3 -// Sets up the FSMC peripheral to use the SRAM chip on the maple native as an -// external segment of system memory space. -// This implementation is for the IS62WV51216BLL 8mbit chip (55ns timing) +/* Sets up the FSMC peripheral to use the SRAM chip on the maple + * native as an external segment of system memory space. This + * implementation is for the IS62WV51216BLL 8mbit chip (55ns + * timing) */ void fsmc_native_sram_init(void) { FSMC_Bank *bank; - // First we setup all the GPIO pins. - // Data lines... + /* 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); @@ -57,7 +57,8 @@ void fsmc_native_sram_init(void) { 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); - // Address lines... + + /* 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); @@ -77,7 +78,8 @@ void fsmc_native_sram_init(void) { 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); - // And control lines... + + /* 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 @@ -88,41 +90,41 @@ void fsmc_native_sram_init(void) { gpio_set_mode(GPIOE_BASE, 0, MODE_AF_OUTPUT_PP); // NBL0 gpio_set_mode(GPIOE_BASE, 1, MODE_AF_OUTPUT_PP); // NBL1 - - // Next enable the clock + + /* Next enable the clock */ rcc_clk_enable(RCC_FSMC); - // Then we configure channel 1 the FSMC SRAM peripheral - // (all SRAM channels are in "Bank 1" of the FSMC) + /* Then we configure channel 1 the FSMC SRAM peripheral (all SRAM + * channels are in "Bank 1" of the FSMC) */ bank = (FSMC_Bank*)(FSMC1_BASE); - - // Everything else is cleared (BCR1) + + /* Everything else is cleared (BCR1) */ bank->BCR = 0x0000; - // Memory type is SRAM + /* Memory type is SRAM */ bank->BCR &= ~(FSMC_BCR_MTYP); // '00' - // Databus width is 16bits - bank->BCR &= ~(FSMC_BCR_MWID); + /* Databus width is 16bits */ + bank->BCR &= ~(FSMC_BCR_MWID); bank->BCR |= 0x1 << 4; // '01' - // Memory is nonmultiplexed + /* Memory is nonmultiplexed */ bank->BCR &= ~(FSMC_BCR_MUXEN); // '0' - // Need write enable to write to the chip + /* Need write enable to write to the chip */ bank->BCR |= FSMC_BCR_WREN; - // Set ADDSET + /* Set ADDSET */ bank->BTR &= ~(FSMC_BTR_ADDSET); bank->BTR |= (FSMC_BTR_ADDSET | FSMC_ADDSET); - // Set DATAST + /* Set DATAST */ bank->BTR &= ~(FSMC_BTR_DATAST); bank->BTR |= (FSMC_BTR_DATAST | (FSMC_DATAST << 8)); - // Enable channel 1 + /* Enable channel 1 */ bank->BCR |= FSMC_BCR_MBKEN; // '1' - // FSMC_BWTR3 not used for this simple configuration. + /* (FSMC_BWTR3 not used for this simple configuration.) */ } diff --git a/libmaple/fsmc.h b/libmaple/fsmc.h index 0ac4084..471cad1 100644 --- a/libmaple/fsmc.h +++ b/libmaple/fsmc.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Bryan Newbold. @@ -20,9 +20,9 @@ * 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. - * ****************************************************************************/ + *****************************************************************************/ -/* +/* * See ../notes/fsmc.txt for more info */ @@ -42,10 +42,10 @@ extern "C"{ #define FSMC4_BASE 0xA0000018 typedef struct { - volatile uint32 BCR; - volatile uint32 BTR; - //uint32 pad[62]; // double check this? - //__io uint32 BWTR; + volatile uint32 BCR; + volatile uint32 BTR; + //uint32 pad[62]; // double check this? + //__io uint32 BWTR; } FSMC_Bank; // And here are the register bit ranges diff --git a/libmaple/gpio.c b/libmaple/gpio.c index c5bb450..f7aee2b 100644 --- a/libmaple/gpio.c +++ b/libmaple/gpio.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,12 +20,12 @@ * 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.c + * @file gpio.c * - * @brief GPIO initialization routine + * @brief GPIO initialization routine */ #include "libmaple.h" @@ -33,39 +33,38 @@ #include "gpio.h" void gpio_init(void) { - rcc_clk_enable(RCC_GPIOA); - rcc_clk_enable(RCC_GPIOB); - rcc_clk_enable(RCC_GPIOC); - rcc_clk_enable(RCC_GPIOD); - #if NR_GPIO_PORTS >= 7 - rcc_clk_enable(RCC_GPIOE); - rcc_clk_enable(RCC_GPIOF); - rcc_clk_enable(RCC_GPIOG); - #endif - rcc_clk_enable(RCC_AFIO); + rcc_clk_enable(RCC_GPIOA); + rcc_clk_enable(RCC_GPIOB); + rcc_clk_enable(RCC_GPIOC); + rcc_clk_enable(RCC_GPIOD); +#if NR_GPIO_PORTS >= 7 + rcc_clk_enable(RCC_GPIOE); + rcc_clk_enable(RCC_GPIOF); + rcc_clk_enable(RCC_GPIOG); +#endif + rcc_clk_enable(RCC_AFIO); } void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, GPIOPinMode mode) { - uint32 tmp; - uint32 shift = POS(gpio_pin % 8); - GPIOReg CR; + uint32 tmp; + uint32 shift = POS(gpio_pin % 8); + GPIOReg CR; - ASSERT(port); - ASSERT(gpio_pin < 16); + ASSERT(port); + ASSERT(gpio_pin < 16); - 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_MODE_INPUT_PU) { + port->ODR |= BIT(gpio_pin); + mode = CNF_INPUT_PD; + } else if (mode == GPIO_MODE_INPUT_PD) { + port->ODR &= ~BIT(gpio_pin); + } - CR = (gpio_pin < 8) ? &(port->CRL) : &(port->CRH); + CR = (gpio_pin < 8) ? &(port->CRL) : &(port->CRH); - tmp = *CR; - tmp &= POS_MASK(shift); - tmp |= mode << shift; - - *CR = tmp; + tmp = *CR; + tmp &= POS_MASK(shift); + tmp |= mode << shift; + *CR = tmp; } diff --git a/libmaple/gpio.h b/libmaple/gpio.h index 9099c9b..49360ee 100644 --- a/libmaple/gpio.h +++ b/libmaple/gpio.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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 @@ -65,24 +65,24 @@ #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, + 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 + 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; @@ -98,15 +98,15 @@ void gpio_init(void); void gpio_set_mode(GPIO_Port* port, uint8 gpio_pin, GPIOPinMode mode); static inline void gpio_write_bit(GPIO_Port *port, uint8 gpio_pin, uint8 val) { - if (val){ - port->BSRR = BIT(gpio_pin); - } else { - port->BRR = BIT(gpio_pin); - } + if (val){ + port->BSRR = BIT(gpio_pin); + } else { + port->BRR = BIT(gpio_pin); + } } static inline uint32 gpio_read_bit(GPIO_Port *port, uint8 gpio_pin) { - return (port->IDR & BIT(gpio_pin) ? 1 : 0); + return (port->IDR & BIT(gpio_pin) ? 1 : 0); } #ifdef __cplusplus diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h index 8124516..6921b63 100644 --- a/libmaple/libmaple.h +++ b/libmaple/libmaple.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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 libmaple.h diff --git a/libmaple/libmaple_types.h b/libmaple/libmaple_types.h index da3c241..a976a9e 100644 --- a/libmaple/libmaple_types.h +++ b/libmaple/libmaple_types.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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 libmaple_types.h diff --git a/libmaple/nvic.c b/libmaple/nvic.c index b911e35..5b32d16 100644 --- a/libmaple/nvic.c +++ b/libmaple/nvic.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,12 +20,12 @@ * 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 nvic.c + * @file nvic.c * - * @brief Nested interrupt controller routines + * @brief Nested interrupt controller routines */ #include "libmaple.h" @@ -33,13 +33,12 @@ #include "systick.h" void nvic_set_vector_table(uint32 addr, uint32 offset) { - __write(SCB_VTOR, (uint32)addr | (offset & 0x1FFFFF80)); + __write(SCB_VTOR, (uint32)addr | (offset & 0x1FFFFF80)); } - /** - * @brief turn on interrupt number n - * @param n interrupt number + * @brief turn on interrupt number n + * @param n interrupt number */ void nvic_irq_enable(uint32 n) { uint32 *iser = &((uint32*)NVIC_ISER0)[(n/32)]; @@ -47,8 +46,8 @@ void nvic_irq_enable(uint32 n) { } /** - * @brief turn off interrupt number n - * @param n interrupt number + * @brief turn off interrupt number n + * @param n interrupt number */ void nvic_irq_disable(uint32 n) { uint32 *icer = &((uint32*)NVIC_ICER0)[(n/32)]; @@ -68,11 +67,11 @@ void nvic_irq_disable_all(void) { */ void nvic_init(void) { #ifdef VECT_TAB_FLASH - nvic_set_vector_table(USER_ADDR_ROM, 0x0); + nvic_set_vector_table(USER_ADDR_ROM, 0x0); #elif defined VECT_TAB_RAM - nvic_set_vector_table(USER_ADDR_RAM, 0x0); + nvic_set_vector_table(USER_ADDR_RAM, 0x0); #elif defined VECT_TAB_BASE - nvic_set_vector_table(((uint32)0x08000000), 0x0); + nvic_set_vector_table(((uint32)0x08000000), 0x0); #else #error "You must set a base address for the vector table!" #endif diff --git a/libmaple/nvic.h b/libmaple/nvic.h index ab56f0e..3cdac5a 100644 --- a/libmaple/nvic.h +++ b/libmaple/nvic.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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 Nested interrupt controller defines and prototypes @@ -55,28 +55,28 @@ extern "C"{ #endif enum { - NVIC_TIMER1 = 27, - NVIC_TIMER2 = 28, - NVIC_TIMER3 = 29, - NVIC_TIMER4 = 30, - NVIC_TIMER5 = 50, // high density only (Maple Native) - NVIC_TIMER6 = 54, // high density only (Maple Native) - NVIC_TIMER7 = 55, // high density only (Maple Native) - NVIC_TIMER8 = 46, // high density only (Maple Native) - - NVIC_USART1 = 37, - NVIC_USART2 = 38, - NVIC_USART3 = 39, - NVIC_USART4 = 52, // high density only (Maple Native) - NVIC_USART5 = 53, // high density only (Maple Native) - - NVIC_EXTI0 = 6, - NVIC_EXTI1 = 7, - NVIC_EXTI2 = 8, - NVIC_EXTI3 = 9, - NVIC_EXTI4 = 10, - NVIC_EXTI9_5 = 23, - NVIC_EXTI15_10 = 40, + NVIC_TIMER1 = 27, + NVIC_TIMER2 = 28, + NVIC_TIMER3 = 29, + NVIC_TIMER4 = 30, + NVIC_TIMER5 = 50, // high density only (Maple Native) + NVIC_TIMER6 = 54, // high density only (Maple Native) + NVIC_TIMER7 = 55, // high density only (Maple Native) + NVIC_TIMER8 = 46, // high density only (Maple Native) + + NVIC_USART1 = 37, + NVIC_USART2 = 38, + NVIC_USART3 = 39, + NVIC_USART4 = 52, // high density only (Maple Native) + NVIC_USART5 = 53, // high density only (Maple Native) + + NVIC_EXTI0 = 6, + NVIC_EXTI1 = 7, + NVIC_EXTI2 = 8, + NVIC_EXTI3 = 9, + NVIC_EXTI4 = 10, + NVIC_EXTI9_5 = 23, + NVIC_EXTI15_10 = 40, }; diff --git a/libmaple/rcc.c b/libmaple/rcc.c index 9bd2663..582e9a9 100644 --- a/libmaple/rcc.c +++ b/libmaple/rcc.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,11 +20,11 @@ * 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 Implements pretty much only the basic clock setup on the stm32, - * clock enable/disable and peripheral reset commands. + * @brief Implements pretty much only the basic clock setup on the + * stm32, clock enable/disable and peripheral reset commands. */ #include "libmaple.h" @@ -32,139 +32,135 @@ #include "rcc.h" enum { - APB1, - APB2, - AHB + APB1, + APB2, + AHB }; struct rcc_dev_info { - const uint8 clk_domain; - const uint8 line_num; + const uint8 clk_domain; + const uint8 line_num; }; /* device descriptor tables */ static const struct rcc_dev_info rcc_dev_table[] = { - [RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 }, - [RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 }, - [RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 }, - [RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 }, - [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, // High-density devices only - [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, // High-density devices only - [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, // High-density devices only - [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, - [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 }, - [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 }, - [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 }, - [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, - [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, - [RCC_USART4] = { .clk_domain = APB1, .line_num = 19 }, // High-density devices only - [RCC_USART5] = { .clk_domain = APB1, .line_num = 20 }, // High-density devices only - [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 }, - [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, - [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, - [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, - [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, // High-density devices only - [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, // High-density devices only - [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, // High-density devices only - [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, // High-density devices only - [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, - [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, - [RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 }, // High-density devices only - [RCC_DAC] = { .clk_domain = APB1, .line_num = 9 }, // High-density devices only + [RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 }, + [RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 }, + [RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 }, + [RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 }, + [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, // High-density only + [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, // High-density only + [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, // High-density only + [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 }, + [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 }, + [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 }, + [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 }, + [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 }, + [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 }, + [RCC_USART4] = { .clk_domain = APB1, .line_num = 19 }, // High-density only + [RCC_USART5] = { .clk_domain = APB1, .line_num = 20 }, // High-density only + [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 }, + [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 }, + [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 }, + [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 }, + [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, // High-density only + [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, // High-density only + [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, // High-density only + [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, // High-density only + [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 }, + [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 }, + [RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 }, // High-density only + [RCC_DAC] = { .clk_domain = APB1, .line_num = 9 }, // High-density only }; /** * @brief Initialize the clock control system. Initializes the system - * clock source to use the PLL driven by an external oscillator + * clock source to use the PLL driven by an external oscillator * @param sysclk_src system clock source, must be PLL * @param pll_src pll clock source, must be HSE * @param pll_mul pll multiplier */ void rcc_clk_init(uint32 sysclk_src, uint32 pll_src, uint32 pll_mul) { - /* Assume that we're going to clock the chip off the PLL, fed by - * the HSE */ - ASSERT(sysclk_src == RCC_CLKSRC_PLL && - pll_src == RCC_PLLSRC_HSE); - - uint32 cfgr = 0; - uint32 cr = RCC_READ_CR(); - - cfgr = (pll_src | pll_mul); - RCC_WRITE_CFGR(cfgr); - - /* Turn on the HSE */ - cr |= RCC_CR_HSEON; - RCC_WRITE_CR(cr); - while (!(RCC_READ_CR() & RCC_CR_HSERDY)) - ; - - /* Now the PLL */ - cr |= RCC_CR_PLLON; - RCC_WRITE_CR(cr); - while (!(RCC_READ_CR() & RCC_CR_PLLRDY)) - ; - - /* Finally, let's switch over to the PLL */ - cfgr &= ~RCC_CFGR_SW; - cfgr |= RCC_CFGR_SW_PLL; - RCC_WRITE_CFGR(cfgr); - while ((RCC_READ_CFGR() & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) - ; + /* Assume that we're going to clock the chip off the PLL, fed by + * the HSE */ + ASSERT(sysclk_src == RCC_CLKSRC_PLL && + pll_src == RCC_PLLSRC_HSE); + + uint32 cfgr = 0; + uint32 cr = RCC_READ_CR(); + + cfgr = (pll_src | pll_mul); + RCC_WRITE_CFGR(cfgr); + + /* Turn on the HSE */ + cr |= RCC_CR_HSEON; + RCC_WRITE_CR(cr); + while (!(RCC_READ_CR() & RCC_CR_HSERDY)) + ; + + /* Now the PLL */ + cr |= RCC_CR_PLLON; + RCC_WRITE_CR(cr); + while (!(RCC_READ_CR() & RCC_CR_PLLRDY)) + ; + + /* Finally, let's switch over to the PLL */ + cfgr &= ~RCC_CFGR_SW; + cfgr |= RCC_CFGR_SW_PLL; + RCC_WRITE_CFGR(cfgr); + while ((RCC_READ_CFGR() & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) + ; } - - /** * @brief Turn on the clock line on a device * @param dev_num device to turn on */ void rcc_clk_enable(uint32 dev_num) { - static const uint32 enable_regs[] = { - [APB1] = RCC_APB1ENR, - [APB2] = RCC_APB2ENR, - [AHB] = RCC_AHBENR, - }; + static const uint32 enable_regs[] = { + [APB1] = RCC_APB1ENR, + [APB2] = RCC_APB2ENR, + [AHB] = RCC_AHBENR, + }; - uint8 clk_domain = rcc_dev_table[dev_num].clk_domain; + uint8 clk_domain = rcc_dev_table[dev_num].clk_domain; - __set_bits(enable_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); + __set_bits(enable_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); } - /** * @brief Set the divider on a device prescaler * @param prescaler prescaler to set * @param divider prescaler divider */ void rcc_set_prescaler(uint32 prescaler, uint32 divider) { - static const uint32 masks[] = { - [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, - [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, - [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, - [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, - [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE, - }; - - uint32 cfgr = RCC_READ_CFGR(); - - cfgr &= ~masks[prescaler]; - cfgr |= divider; - RCC_WRITE_CFGR(cfgr); + static const uint32 masks[] = { + [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE, + [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1, + [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2, + [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE, + [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE, + }; + + uint32 cfgr = RCC_READ_CFGR(); + + cfgr &= ~masks[prescaler]; + cfgr |= divider; + RCC_WRITE_CFGR(cfgr); } - /** * @brief reset a device * @param dev_num device to reset */ void rcc_reset_dev(uint32 dev_num) { - static const uint32 reset_regs[] = { - [APB1] = RCC_APB1RSTR, - [APB2] = RCC_APB2RSTR, - }; + static const uint32 reset_regs[] = { + [APB1] = RCC_APB1RSTR, + [APB2] = RCC_APB2RSTR, + }; - uint8 clk_domain = rcc_dev_table[dev_num].clk_domain; + uint8 clk_domain = rcc_dev_table[dev_num].clk_domain; - __set_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); - __clear_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); + __set_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); + __clear_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num)); } diff --git a/libmaple/rcc.h b/libmaple/rcc.h index 3651945..f245fe9 100644 --- a/libmaple/rcc.h +++ b/libmaple/rcc.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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 reset and clock control definitions and prototypes @@ -132,42 +132,42 @@ /* prescalers */ enum { - RCC_PRESCALER_AHB, - RCC_PRESCALER_APB1, - RCC_PRESCALER_APB2, - RCC_PRESCALER_USB, - RCC_PRESCALER_ADC + RCC_PRESCALER_AHB, + RCC_PRESCALER_APB1, + RCC_PRESCALER_APB2, + RCC_PRESCALER_USB, + RCC_PRESCALER_ADC }; // RCC Devices enum { - RCC_GPIOA, - RCC_GPIOB, - RCC_GPIOC, - RCC_GPIOD, - RCC_GPIOE, // High-density devices only (Maple Native) - RCC_GPIOF, // High-density devices only (Maple Native) - RCC_GPIOG, // High-density devices only (Maple Native) - RCC_AFIO, - RCC_ADC1, - RCC_ADC2, - RCC_USART1, - RCC_USART2, - RCC_USART3, - RCC_USART4, // High-density devices only (Maple Native) - RCC_USART5, // High-density devices only (Maple Native) - RCC_TIMER1, - RCC_TIMER2, - RCC_TIMER3, - RCC_TIMER4, - RCC_TIMER5, // High-density devices only (Maple Native) - RCC_TIMER6, // High-density devices only (Maple Native) - RCC_TIMER7, // High-density devices only (Maple Native) - RCC_TIMER8, // High-density devices only (Maple Native) - RCC_SPI1, - RCC_SPI2, - RCC_FSMC, // High-density devices only (Maple Native) - RCC_DAC, // High-density devices only (Maple Native) + RCC_GPIOA, + RCC_GPIOB, + RCC_GPIOC, + RCC_GPIOD, + RCC_GPIOE, // High-density devices only (Maple Native) + RCC_GPIOF, // High-density devices only (Maple Native) + RCC_GPIOG, // High-density devices only (Maple Native) + RCC_AFIO, + RCC_ADC1, + RCC_ADC2, + RCC_USART1, + RCC_USART2, + RCC_USART3, + RCC_USART4, // High-density devices only (Maple Native) + RCC_USART5, // High-density devices only (Maple Native) + RCC_TIMER1, + RCC_TIMER2, + RCC_TIMER3, + RCC_TIMER4, + RCC_TIMER5, // High-density devices only (Maple Native) + RCC_TIMER6, // High-density devices only (Maple Native) + RCC_TIMER7, // High-density devices only (Maple Native) + RCC_TIMER8, // High-density devices only (Maple Native) + RCC_SPI1, + RCC_SPI2, + RCC_FSMC, // High-density devices only (Maple Native) + RCC_DAC, // High-density devices only (Maple Native) }; diff --git a/libmaple/ring_buffer.h b/libmaple/ring_buffer.h index 95b9dd8..6a54747 100644 --- a/libmaple/ring_buffer.h +++ b/libmaple/ring_buffer.h @@ -21,30 +21,30 @@ typedef struct ring_buffer { } ring_buffer; static inline void rb_init(ring_buffer *rb, uint8 size, uint8 *buf) { - ASSERT(IS_POWER_OF_TWO(size)); - rb->head = 0; - rb->tail = 0; - rb->size = size; - rb->buf = buf; + ASSERT(IS_POWER_OF_TWO(size)); + rb->head = 0; + rb->tail = 0; + rb->size = size; + rb->buf = buf; } static inline void rb_insert(ring_buffer *rb, uint8 element) { - rb->buf[(rb->tail)++] = element; - rb->tail &= (rb->size - 1); + rb->buf[(rb->tail)++] = element; + rb->tail &= (rb->size - 1); } static inline uint8 rb_remove(ring_buffer *rb) { - uint8 ch = rb->buf[rb->head++]; - rb->head &= (rb->size - 1); - return ch; + uint8 ch = rb->buf[rb->head++]; + rb->head &= (rb->size - 1); + return ch; } static inline uint32 rb_full_count(ring_buffer *rb) { - return rb->tail - rb->head; + return rb->tail - rb->head; } static inline void rb_reset(ring_buffer *rb) { - rb->tail = rb->head; + rb->tail = rb->head; } #ifdef __cplusplus diff --git a/libmaple/spi.c b/libmaple/spi.c index 4b02f44..8bba0d6 100644 --- a/libmaple/spi.c +++ b/libmaple/spi.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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 libmaple serial peripheral interface (SPI) definitions @@ -42,27 +42,27 @@ #include "spi.h" typedef struct spi_dev { - SPI *base; - GPIO_Port *port; - uint8 sck_pin; - uint8 miso_pin; - uint8 mosi_pin; + SPI *base; + GPIO_Port *port; + uint8 sck_pin; + uint8 miso_pin; + uint8 mosi_pin; } spi_dev; static const spi_dev spi_dev1 = { - .base = (SPI*)SPI1_BASE, - .port = GPIOA_BASE, - .sck_pin = 5, - .miso_pin = 6, - .mosi_pin = 7 + .base = (SPI*)SPI1_BASE, + .port = GPIOA_BASE, + .sck_pin = 5, + .miso_pin = 6, + .mosi_pin = 7 }; static const spi_dev spi_dev2 = { - .base = (SPI*)SPI2_BASE, - .port = GPIOB_BASE, - .sck_pin = 13, - .miso_pin = 14, - .mosi_pin = 15 + .base = (SPI*)SPI2_BASE, + .port = GPIOB_BASE, + .sck_pin = 13, + .miso_pin = 14, + .mosi_pin = 15 }; static void spi_gpio_cfg(const spi_dev *dev); @@ -78,85 +78,84 @@ void spi_init(uint32 spi_num, uint32 prescale, uint32 endian, uint32 mode) { - ASSERT(spi_num == 1 || spi_num == 2); - ASSERT(mode < 4); - - SPI *spi; - uint32 cr1 = 0; - - switch (spi_num) { - case 1: - /* limit to 18 mhz max speed */ - ASSERT(prescale != CR1_BR_PRESCALE_2); - spi = (SPI*)SPI1_BASE; - rcc_clk_enable(RCC_SPI1); - spi_gpio_cfg(&spi_dev1); - break; - case 2: - spi = (SPI*)SPI2_BASE; - rcc_clk_enable(RCC_SPI2); - spi_gpio_cfg(&spi_dev2); - break; - } - - cr1 = prescale | endian | mode | CR1_MSTR | CR1_SSI | CR1_SSM; - spi->CR1 = cr1; - - /* Peripheral enable */ - spi->CR1 |= CR1_SPE; + ASSERT(spi_num == 1 || spi_num == 2); + ASSERT(mode < 4); + + SPI *spi; + uint32 cr1 = 0; + + switch (spi_num) { + case 1: + /* limit to 18 mhz max speed */ + ASSERT(prescale != CR1_BR_PRESCALE_2); + spi = (SPI*)SPI1_BASE; + rcc_clk_enable(RCC_SPI1); + spi_gpio_cfg(&spi_dev1); + break; + case 2: + spi = (SPI*)SPI2_BASE; + rcc_clk_enable(RCC_SPI2); + spi_gpio_cfg(&spi_dev2); + break; + } + + cr1 = prescale | endian | mode | CR1_MSTR | CR1_SSI | CR1_SSM; + spi->CR1 = cr1; + + /* Peripheral enable */ + spi->CR1 |= CR1_SPE; } - /** * @brief SPI synchronous 8-bit write, blocking. * @param spi_num which spi to send on * @return data shifted back from the slave */ uint8 spi_tx_byte(uint32 spi_num, uint8 data) { - SPI *spi; + SPI *spi; - spi = (spi_num == 1) ? (SPI*)SPI1_BASE : (SPI*)SPI2_BASE; + spi = (spi_num == 1) ? (SPI*)SPI1_BASE : (SPI*)SPI2_BASE; - while (!(spi->SR & SR_TXE)) - ; + while (!(spi->SR & SR_TXE)) + ; - spi->DR = data; + spi->DR = data; - while (!(spi->SR & SR_RXNE)) - ; + while (!(spi->SR & SR_RXNE)) + ; - return spi->DR; + return spi->DR; } uint8 spi_tx(uint32 spi_num, uint8 *buf, uint32 len) { - SPI *spi; - uint32 i = 0; - uint8 rc; + SPI *spi; + uint32 i = 0; + uint8 rc; - ASSERT(spi_num == 1 || spi_num == 2); - spi = (spi_num == 1) ? (SPI*)SPI1_BASE : (SPI*)SPI2_BASE; + ASSERT(spi_num == 1 || spi_num == 2); + spi = (spi_num == 1) ? (SPI*)SPI1_BASE : (SPI*)SPI2_BASE; - if (!len) { - return 0; - } + if (!len) { + return 0; + } - while (i < len) { - while (!(spi->SR & SR_TXE)) - ; + while (i < len) { + while (!(spi->SR & SR_TXE)) + ; - spi->DR = buf[i]; + spi->DR = buf[i]; - while (!(spi->SR & SR_RXNE)) - ; + while (!(spi->SR & SR_RXNE)) + ; - rc = spi->DR; - i++; - } - return rc; + rc = spi->DR; + i++; + } + return rc; } 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->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); } diff --git a/libmaple/spi.h b/libmaple/spi.h index 742c1d0..d1973c5 100644 --- a/libmaple/spi.h +++ b/libmaple/spi.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,10 +20,11 @@ * 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 libmaple serial peripheral interface (SPI) prototypes and declarations + * @brief libmaple serial peripheral interface (SPI) prototypes and + * declarations */ #ifndef _SPI_H_ @@ -61,36 +62,36 @@ extern "C" { #define SR_BSY BIT(7) // busy flag typedef struct SPI { - __io uint16 CR1; - uint16 pad0; - __io uint8 CR2; - uint8 pad1[3]; - __io uint8 SR; - uint8 pad2[3]; - __io uint16 DR; - uint16 pad3; - __io uint16 CRCPR; - uint16 pad4; - __io uint16 RXCRCR; - uint16 pad5; - __io uint16 TXCRCR; - uint16 pad6; + __io uint16 CR1; + uint16 pad0; + __io uint8 CR2; + uint8 pad1[3]; + __io uint8 SR; + uint8 pad2[3]; + __io uint16 DR; + uint16 pad3; + __io uint16 CRCPR; + uint16 pad4; + __io uint16 RXCRCR; + uint16 pad5; + __io uint16 TXCRCR; + uint16 pad6; } SPI; enum { - SPI_MSBFIRST = 0, - SPI_LSBFIRST = BIT(7), + SPI_MSBFIRST = 0, + SPI_LSBFIRST = BIT(7), }; enum { - SPI_PRESCALE_2 = (0x0 << 3), - SPI_PRESCALE_4 = (0x1 << 3), - SPI_PRESCALE_8 = (0x2 << 3), - SPI_PRESCALE_16 = (0x3 << 3), - SPI_PRESCALE_32 = (0x4 << 3), - SPI_PRESCALE_64 = (0x5 << 3), - SPI_PRESCALE_128 = (0x6 << 3), - SPI_PRESCALE_256 = (0x7 << 3) + SPI_PRESCALE_2 = (0x0 << 3), + SPI_PRESCALE_4 = (0x1 << 3), + SPI_PRESCALE_8 = (0x2 << 3), + SPI_PRESCALE_16 = (0x3 << 3), + SPI_PRESCALE_32 = (0x4 << 3), + SPI_PRESCALE_64 = (0x5 << 3), + SPI_PRESCALE_128 = (0x6 << 3), + SPI_PRESCALE_256 = (0x7 << 3) }; void spi_init(uint32 spi_num, @@ -101,12 +102,12 @@ uint8 spi_tx_byte(uint32 spi_num, uint8 data); uint8 spi_tx(uint32 spi_num, uint8 *buf, uint32 len); static inline uint8 spi_rx(uint32 spi_num) { - SPI *spi; + SPI *spi; - ASSERT(spi_num == 1 || spi_num == 2); - spi = (spi_num == 1) ? (SPI*)SPI1_BASE : (SPI*)SPI2_BASE; + ASSERT(spi_num == 1 || spi_num == 2); + spi = (spi_num == 1) ? (SPI*)SPI1_BASE : (SPI*)SPI2_BASE; - return spi->DR; + return spi->DR; } #ifdef __cplusplus diff --git a/libmaple/syscalls.c b/libmaple/syscalls.c index ec271a2..5611ce5 100644 --- a/libmaple/syscalls.c +++ b/libmaple/syscalls.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * ****************************************************************************/ + *****************************************************************************/ #include "libmaple.h" #include @@ -35,10 +35,7 @@ void uart_send(const char*str); * RAM. We just increment a pointer in what's * left of memory on the board. */ -caddr_t -_sbrk(nbytes) -int nbytes; -{ +caddr_t _sbrk(int nbytes) { static caddr_t heap_ptr = NULL; caddr_t base; @@ -56,62 +53,52 @@ int nbytes; } } -int _open(const char *path, int flags, ...) -{ +int _open(const char *path, int flags, ...) { return 1; } -int _close(int fd) -{ +int _close(int fd) { return 0; } -int _fstat(int fd, struct stat *st) -{ +int _fstat(int fd, struct stat *st) { st->st_mode = S_IFCHR; return 0; } -int _isatty(int fd) -{ +int _isatty(int fd) { return 1; } -int isatty(int fd) -{ +int isatty(int fd) { return 1; } -int _lseek(int fd, off_t pos, int whence) -{ +int _lseek(int fd, off_t pos, int whence) { return -1; } -unsigned char getch(void) -{ +unsigned char getch(void) { // while (!(USART2->SR & USART_FLAG_RXNE)); // return USART2->DR; return 0; } -int _read(int fd, char *buf, size_t cnt) -{ +int _read(int fd, char *buf, size_t cnt) { *buf = getch(); return 1; } -void putch(unsigned char c) -{ +void putch(unsigned char c) { // if (c == '\n') putch('\r'); // while (!(USART2->SR & USART_FLAG_TXE)); // USART2->DR = c; } -void cgets(char *s, int bufsize) -{ +void cgets(char *s, int bufsize) { char *p; int c; int i; @@ -123,11 +110,9 @@ void cgets(char *s, int bufsize) p = s; - for (p = s; p < s + bufsize-1;) - { + for (p = s; p < s + bufsize-1;) { c = getch(); - switch (c) - { + switch (c) { case '\r' : case '\n' : putch('\r'); @@ -136,8 +121,7 @@ void cgets(char *s, int bufsize) return; case '\b' : - if (p > s) - { + if (p > s) { *p-- = 0; putch('\b'); putch(' '); @@ -154,8 +138,7 @@ void cgets(char *s, int bufsize) return; } -int _write(int fd, const char *buf, size_t cnt) -{ +int _write(int fd, const char *buf, size_t cnt) { int i; // uart_send("_write\r\n"); @@ -166,8 +149,7 @@ int _write(int fd, const char *buf, size_t cnt) } /* Override fgets() in newlib with a version that does line editing */ -char *fgets(char *s, int bufsize, void *f) -{ +char *fgets(char *s, int bufsize, void *f) { // uart_send("fgets\r\n"); cgets(s, bufsize); return s; diff --git a/libmaple/systick.c b/libmaple/systick.c index 9fbb152..12a3e22 100644 --- a/libmaple/systick.c +++ b/libmaple/systick.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,12 +20,12 @@ * 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 systick.c + * @file systick.c * - * @brief System timer interrupt handler and initialization routines + * @brief System timer interrupt handler and initialization routines */ #include "libmaple.h" @@ -45,24 +45,24 @@ void systick_init(uint32 reload_val) { /* Set the reload counter to tick every 1ms */ __write(SYSTICK_RELOAD, reload_val); - /* Clock the system timer with the core clock - * and turn it on, interrrupt every 1ms to keep track of millis()*/ + /* Clock the system timer with the core clock and turn it on, + * interrrupt every 1ms to keep track of millis() */ __write(SYSTICK_CSR, SYSTICK_SRC_HCLK | - SYSTICK_ENABLE | - SYSTICK_TICKINT); + SYSTICK_ENABLE | + SYSTICK_TICKINT); } void systick_disable() { - /* clock the system timer with the core clock, but don't turn it on - or enable interrupt. */ - __write(SYSTICK_CSR, SYSTICK_SRC_HCLK); + /* clock the system timer with the core clock, but don't turn it + on or enable interrupt. */ + __write(SYSTICK_CSR, SYSTICK_SRC_HCLK); } void systick_resume() { - /* re-enable init registers without changing relead_val */ - __write(SYSTICK_CSR, SYSTICK_SRC_HCLK | - SYSTICK_ENABLE | - SYSTICK_TICKINT); + /* re-enable init registers without changing relead_val */ + __write(SYSTICK_CSR, SYSTICK_SRC_HCLK | + SYSTICK_ENABLE | + SYSTICK_TICKINT); } void SysTickHandler(void) { diff --git a/libmaple/systick.h b/libmaple/systick.h index 80e2fde..7ec8497 100644 --- a/libmaple/systick.h +++ b/libmaple/systick.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,12 +20,12 @@ * 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 systick.h + * @file systick.h * - * @brief Various system timer definitions + * @brief Various system timer definitions */ #ifndef _SYSTICK_H_ @@ -51,7 +51,7 @@ static inline uint32 systick_get_count(void) { } static inline uint32 systick_check_underflow(void) { - return (__read(SYSTICK_CSR) & SYSTICK_CSR_COUNTFLAG); + return (__read(SYSTICK_CSR) & SYSTICK_CSR_COUNTFLAG); } #ifdef __cplusplus diff --git a/libmaple/timers.c b/libmaple/timers.c index 266ac76..04bfa9f 100644 --- a/libmaple/timers.c +++ b/libmaple/timers.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,63 +20,64 @@ * 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 timers.c + * @file timers.c * - * @brief General timer routines + * @brief General timer routines */ -// TODO: actually support timer5 and timer8 +/* TODO: actually support timer5 and timer8 */ #include "libmaple.h" #include "rcc.h" #include "nvic.h" #include "timers.h" -// Timer descriptor table +/* Timer descriptor table */ struct timer_dev timer_dev_table[] = { - [TIMER1] = { - .base = (timer_port*)TIMER1_BASE, - .rcc_dev_num = RCC_TIMER1, - .nvic_dev_num = NVIC_TIMER1 - }, - [TIMER2] = { - .base = (timer_port*)TIMER2_BASE, - .rcc_dev_num = RCC_TIMER2, - .nvic_dev_num = NVIC_TIMER2 - }, - [TIMER3] = { - .base = (timer_port*)TIMER3_BASE, - .rcc_dev_num = RCC_TIMER3, - .nvic_dev_num = NVIC_TIMER3 - }, - [TIMER4] = { - .base = (timer_port*)TIMER4_BASE, - .rcc_dev_num = RCC_TIMER4, - .nvic_dev_num = NVIC_TIMER4 - }, - #if NR_TIMERS >= 8 - // High density devices only (eg, Maple Native) - [TIMER5] = { - .base = (timer_port*)TIMER5_BASE, - .rcc_dev_num = RCC_TIMER5, - .nvic_dev_num = NVIC_TIMER5 - }, - [TIMER8] = { - .base = (timer_port*)TIMER8_BASE, - .rcc_dev_num = RCC_TIMER8, - .nvic_dev_num = NVIC_TIMER8 - }, - #endif + [TIMER1] = { + .base = (timer_port*)TIMER1_BASE, + .rcc_dev_num = RCC_TIMER1, + .nvic_dev_num = NVIC_TIMER1 + }, + [TIMER2] = { + .base = (timer_port*)TIMER2_BASE, + .rcc_dev_num = RCC_TIMER2, + .nvic_dev_num = NVIC_TIMER2 + }, + [TIMER3] = { + .base = (timer_port*)TIMER3_BASE, + .rcc_dev_num = RCC_TIMER3, + .nvic_dev_num = NVIC_TIMER3 + }, + [TIMER4] = { + .base = (timer_port*)TIMER4_BASE, + .rcc_dev_num = RCC_TIMER4, + .nvic_dev_num = NVIC_TIMER4 + }, +#if NR_TIMERS >= 8 + /* High density devices only (eg, Maple Native) */ + [TIMER5] = { + .base = (timer_port*)TIMER5_BASE, + .rcc_dev_num = RCC_TIMER5, + .nvic_dev_num = NVIC_TIMER5 + }, + [TIMER8] = { + .base = (timer_port*)TIMER8_BASE, + .rcc_dev_num = RCC_TIMER8, + .nvic_dev_num = NVIC_TIMER8 + }, +#endif }; -// This function should probably be rewriten to take (timer_num, mode) and have -// prescaler set elsewhere. The mode can be passed through to set_mode at the -// end +/* This function should probably be rewriten to take (timer_num, mode) + * and have prescaler set elsewhere. The mode can be passed through to + * set_mode at the end */ void timer_init(uint8 timer_num, uint16 prescale) { - ASSERT((timer_num != TIMER6) && (timer_num != TIMER7)); // TODO: doesn't catch 6+7 + /* TODO: doesn't catch 6+7 */ + ASSERT((timer_num != TIMER6) && (timer_num != TIMER7)); timer_port *timer = timer_dev_table[timer_num].base; uint8 is_advanced = 0; @@ -129,124 +130,128 @@ void timer_init(uint8 timer_num, uint16 prescale) { timer->CR1 |= 1; // Enable timer } -// Stops the counter; the mode and settings are not modified -void timer_pause(uint8 timer_num) { +/* Stops the counter; the mode and settings are not modified */ +void timer_pause(uint8 timer_num) { timer_port *timer = timer_dev_table[timer_num].base; timer->CR1 &= ~(0x0001); // CEN } -// Starts the counter; the mode and settings are not modified -void timer_resume(uint8 timer_num) { +/* Starts the counter; the mode and settings are not modified */ +void timer_resume(uint8 timer_num) { timer_port *timer = timer_dev_table[timer_num].base; timer->CR1 |= 0x0001; // CEN } -// This function sets the counter value via register for the specified timer. -// Can't think of specific usecases except for resetting to zero but it's easy -// to implement and allows for "creative" programming -void timer_set_count(uint8 timer_num, uint16 value) { +/* This function sets the counter value via register for the specified + * timer. Can't think of specific usecases except for resetting to + * zero but it's easy to implement and allows for "creative" + * programming */ +void timer_set_count(uint8 timer_num, uint16 value) { timer_port *timer = timer_dev_table[timer_num].base; timer->CNT = value; } -// Returns the current timer counter value. Probably very inaccurate if the -// counter is running with a low prescaler. +/* Returns the current timer counter value. Probably very inaccurate + * if the counter is running with a low prescaler. */ uint16 timer_get_count(uint8 timer_num) { timer_port *timer = timer_dev_table[timer_num].base; return timer->CNT; } -// Does what it says +/* Sets the prescaler */ void timer_set_prescaler(uint8 timer_num, uint16 prescale) { timer_port *timer = timer_dev_table[timer_num].base; timer->PSC = prescale; } -// This sets the "reload" or "overflow" value for the entire timer. We should -// probably settle on either "reload" or "overflow" to prevent confusion? +/* This sets the "reload" or "overflow" value for the entire timer. We + * should probably settle on either "reload" or "overflow" to prevent + * confusion? */ void timer_set_reload(uint8 timer_num, uint16 max_reload) { timer_port *timer = timer_dev_table[timer_num].base; timer->ARR = max_reload; } -// This quickly disables all 4 timers, presumably as part of a system shutdown -// or similar to prevent interrupts and PWM output without 16 seperate function -// calls to timer_set_mode +/* This quickly disables all 4 timers, presumably as part of a system shutdown + * or similar to prevent interrupts and PWM output without 16 seperate function + * calls to timer_set_mode */ void timer_disable_all(void) { // TODO: refactor - // Note: this must be very robust because it gets called from, eg, ASSERT - timer_port *timer; - #if NR_TIMERS >= 8 + + /* Note: this must be very robust because it gets called from, + e.g., ASSERT */ + timer_port *timer; +#if NR_TIMERS >= 8 timer_port *timers[6] = { (timer_port*)TIMER1_BASE, - (timer_port*)TIMER2_BASE, - (timer_port*)TIMER3_BASE, - (timer_port*)TIMER4_BASE, - (timer_port*)TIMER5_BASE, - (timer_port*)TIMER8_BASE, - }; + (timer_port*)TIMER2_BASE, + (timer_port*)TIMER3_BASE, + (timer_port*)TIMER4_BASE, + (timer_port*)TIMER5_BASE, + (timer_port*)TIMER8_BASE, + }; uint8 i; - for (i = 0; i < 6; i++) { - timer = timers[i]; - timer->CR1 = 0; - timer->CCER = 0; + for (i = 0; i < 6; i++) { + timer = timers[i]; + timer->CR1 = 0; + timer->CCER = 0; } - #else +#else timer_port *timers[4] = { (timer_port*)TIMER1_BASE, - (timer_port*)TIMER2_BASE, - (timer_port*)TIMER3_BASE, - (timer_port*)TIMER4_BASE, - }; + (timer_port*)TIMER2_BASE, + (timer_port*)TIMER3_BASE, + (timer_port*)TIMER4_BASE, + }; uint8 i; - for (i = 0; i < 4; i++) { - timer = timers[i]; - timer->CR1 = 0; - timer->CCER = 0; + for (i = 0; i < 4; i++) { + timer = timers[i]; + timer->CR1 = 0; + timer->CCER = 0; } - #endif +#endif } -// Sets the mode of individual timer channels, including a DISABLE mode +/* Sets the mode of individual timer channels, including a DISABLE mode */ void timer_set_mode(uint8 timer_num, uint8 channel, uint8 mode) { timer_port *timer = timer_dev_table[timer_num].base; ASSERT(channel >= 1); switch(mode) { case TIMER_DISABLED: - // Disable the channel - // Disable any interrupt - // Clear interrupt SR? (TODO) + /* Disable the channel + * Disable any interrupt + * Clear interrupt SR? (TODO) */ timer->DIER &= ~(1 << channel); // 1-indexed compare nums timer_detach_interrupt(timer_num, channel); - timer->CCER &= ~(1 << (4*(channel - 1))); // 0-indexed + timer->CCER &= ~(1 << (4*(channel - 1))); // 0-indexed break; case TIMER_PWM: - // Set CCMR mode - // Keep existing reload value - // Disable any interrupt - // Clear interrupt SR? (TODO) - // Enable channel + /* Set CCMR mode + * Keep existing reload value + * Disable any interrupt + * Clear interrupt SR? (TODO) + * Enable channel */ timer->DIER &= ~(1 << channel); // 1-indexed compare nums switch (channel) { case 1: - timer->CCMR1 &= ~(0xFF); + timer->CCMR1 &= ~(0xFF); timer->CCMR1 |= 0x68; // PWM mode 1, enable preload register. break; case 2: - timer->CCMR1 &= ~(0xFF00); + timer->CCMR1 &= ~(0xFF00); timer->CCMR1 |= (0x68 << 8);// PWM mode 1, enable preload register. break; case 3: - timer->CCMR2 &= ~(0xFF); + timer->CCMR2 &= ~(0xFF); timer->CCMR2 |= 0x68; // PWM mode 1, enable preload register. break; case 4: - timer->CCMR2 &= ~(0xFF00); + timer->CCMR2 &= ~(0xFF00); timer->CCMR2 |= (0x68 << 8);// PWM mode 1, enable preload register. break; default: @@ -255,27 +260,27 @@ void timer_set_mode(uint8 timer_num, uint8 channel, uint8 mode) { timer->CCER |= (1 << (4*(channel - 1))); // Enable break; case TIMER_OUTPUTCOMPARE: - // Set CCMR mode - // Keep existing reload value - // Don't modify interrupt (needs to be attached to enable) - // Clear interrupt SR? (TODO) - // Enable channel + /* Set CCMR mode + * Keep existing reload value + * Don't modify interrupt (needs to be attached to enable) + * Clear interrupt SR? (TODO) + * Enable channel */ switch (channel) { case 1: - timer->CCMR1 &= ~(0xFF); - timer->CCMR1 |= 0x0010; // PWM mode 1, enable preload register. + timer->CCMR1 &= ~(0xFF); + timer->CCMR1 |= 0x0010; // PWM mode 1, enable preload register. break; case 2: - timer->CCMR1 &= ~(0xFF00); - timer->CCMR1 |= 0x1000; // PWM mode 1, enable preload register. + timer->CCMR1 &= ~(0xFF00); + timer->CCMR1 |= 0x1000; // PWM mode 1, enable preload register. break; case 3: - timer->CCMR2 &= ~(0xFF); - timer->CCMR2 |= 0x0010; // PWM mode 1, enable preload register. + timer->CCMR2 &= ~(0xFF); + timer->CCMR2 |= 0x0010; // PWM mode 1, enable preload register. break; case 4: - timer->CCMR2 &= ~(0xFF00); - timer->CCMR2 |= 0x1000; // PWM mode 1, enable preload register. + timer->CCMR2 &= ~(0xFF00); + timer->CCMR2 |= 0x1000; // PWM mode 1, enable preload register. break; default: ASSERT(0); @@ -287,12 +292,15 @@ void timer_set_mode(uint8 timer_num, uint8 channel, uint8 mode) { } } -// This sets the compare value (aka the trigger) for a given timer channel -void timer_set_compare_value(uint8 timer_num, uint8 compare_num, uint16 value) { - // The faster version of this function is the inline timer_pwm_write_ccr - // +/* This sets the compare value (aka the trigger) for a given timer + * channel */ +void timer_set_compare_value(uint8 timer_num, + uint8 compare_num, + uint16 value) { + /* The faster version of this function is the inline + timer_pwm_write_ccr */ timer_port *timer = timer_dev_table[timer_num].base; - + ASSERT(compare_num > 0 && compare_num <= 4); switch(compare_num) { @@ -311,9 +319,11 @@ void timer_set_compare_value(uint8 timer_num, uint8 compare_num, uint16 value) { } } -// Stores a pointer to the passed usercode interrupt function and configures -// the actual ISR so that it will actually be called -void timer_attach_interrupt(uint8 timer_num, uint8 compare_num, voidFuncPtr handler) { +/* Stores a pointer to the passed usercode interrupt function and configures + * the actual ISR so that it will actually be called */ +void timer_attach_interrupt(uint8 timer_num, + uint8 compare_num, + voidFuncPtr handler) { ASSERT(compare_num > 0 && compare_num <= 4); timer_port *timer = timer_dev_table[timer_num].base; @@ -332,21 +342,21 @@ void timer_detach_interrupt(uint8 timer_num, uint8 compare_num) { timer->DIER &= ~(1 << compare_num); // 1-indexed compare nums } -// The following are the actual interrupt handlers; 1 for each timer which must -// determine which actual compare value (aka channel) was triggered. -// -// These ISRs get called when the timer interrupt is enabled, the timer is running, and -// the timer count equals any of the CCR registers /or/ has overflowed. -// -// This is a rather long implementation... +/* The following are the actual interrupt handlers; 1 for each timer which must + * determine which actual compare value (aka channel) was triggered. + * + * These ISRs get called when the timer interrupt is enabled, the + * timer is running, and the timer count equals any of the CCR + * registers /or/ has overflowed. + * + * This is a rather long implementation... */ void TIM1_CC_IRQHandler(void) { timer_port *timer = (timer_port*)TIMER1_BASE; - uint16 sr_buffer; + uint16 sr_buffer; sr_buffer = timer->SR; - - // Simply switch/case-ing here doesn't work because multiple - // CC flags may be high. + /* Simply switch/case-ing here doesn't work because multiple + * CC flags may be high. */ if(sr_buffer & 0x10){ // CC4 flag timer->SR &= ~(0x10); if(timer_dev_table[TIMER1].handlers[3]) { @@ -377,9 +387,9 @@ void TIM1_CC_IRQHandler(void) { } } void TIM2_IRQHandler(void) { - // This is a rather long implementation... + /* This is a rather long implementation... */ timer_port *timer = (timer_port*)TIMER2_BASE; - uint16 sr_buffer; + uint16 sr_buffer; sr_buffer = timer->SR; if(sr_buffer & 0x10){ // CC4 flag @@ -412,9 +422,9 @@ void TIM2_IRQHandler(void) { } } void TIM3_IRQHandler(void) { - // This is a rather long implementation... + /* This is a rather long implementation... */ timer_port *timer = (timer_port*)TIMER3_BASE; - uint16 sr_buffer; + uint16 sr_buffer; sr_buffer = timer->SR; if(sr_buffer & 0x10){ // CC4 flag @@ -448,9 +458,9 @@ void TIM3_IRQHandler(void) { } void TIM4_IRQHandler(void) { - // This is a rather long implementation... + /* This is a rather long implementation... */ timer_port*timer = (timer_port*)TIMER4_BASE; - uint16 sr_buffer; + uint16 sr_buffer; sr_buffer = timer->SR; if(sr_buffer & 0x10){ // CC4 flag @@ -482,4 +492,3 @@ void TIM4_IRQHandler(void) { //timer->EGR = 1; } } - diff --git a/libmaple/timers.h b/libmaple/timers.h index 448a533..cbdf088 100644 --- a/libmaple/timers.h +++ b/libmaple/timers.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,12 +20,12 @@ * 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 timers.h + * @file timers.h * - * @brief Timer prototypes and various definitions + * @brief Timer prototypes and various definitions */ /* Note to self: @@ -39,7 +39,7 @@ * See stm32 manual, 77/995 * * hence, 72 mhz timers - * */ + */ /* Maple Timer channels: * Timer Maple Pin STM32 Pin Type @@ -75,7 +75,6 @@ * pinMode(digitalPin, PWM); * pwmWrite(digitalPin) */ - #ifndef _TIMERS_H_ #define _TIMERS_H_ @@ -89,15 +88,14 @@ typedef volatile uint32* TimerCCR; #define TIMER2_BASE 0x40000000 #define TIMER3_BASE 0x40000400 #define TIMER4_BASE 0x40000800 -#define TIMER5_BASE 0x40000C00 // High-density devices only (Maple Native) -#define TIMER6_BASE 0x40001000 // High-density devices only (Maple Native) -#define TIMER7_BASE 0x40001400 // High-density devices only (Maple Native) -#define TIMER8_BASE 0x40013400 // High-density devices only (Maple Native) +#define TIMER5_BASE 0x40000C00 // High-density devices only +#define TIMER6_BASE 0x40001000 // High-density devices only +#define TIMER7_BASE 0x40001400 // High-density devices only +#define TIMER8_BASE 0x40013400 // High-density devices only -#define ARPE BIT(7) // Auto-reload preload enable +#define ARPE BIT(7) // Auto-reload preload enable #define NOT_A_TIMER 0 -// just threw this in here cause I can, aw yeah #define TIMER_CCR(NUM,CHAN) TIMER ## NUM ## _CH ## CHAN ## _CRR #define TIMER1_CH1_CCR (TimerCCR)(TIMER1_BASE + 0x34) @@ -120,8 +118,9 @@ typedef volatile uint32* TimerCCR; #define TIMER4_CH3_CCR (TimerCCR)(TIMER4_BASE + 0x3C) #define TIMER4_CH4_CCR (TimerCCR)(TIMER4_BASE + 0x40) -// Timer5 and Timer8 are in high-density devices only (such as Maple Native). -// Timer6 and Timer7 in these devices have no output compare pins. +/* Timer5 and Timer8 are in high-density devices only (such as Maple + Native). Timer6 and Timer7 in these devices have no output compare + pins. */ #define TIMER5_CH1_CCR (TimerCCR)(TIMER5_BASE + 0x34) #define TIMER5_CH2_CCR (TimerCCR)(TIMER5_BASE + 0x38) @@ -180,24 +179,24 @@ typedef struct { uint16 RESERVED19; } timer_port; -// timer device numbers +/* timer device numbers */ enum { - TIMER1, - TIMER2, - TIMER3, - TIMER4, - TIMER5, // High density only - TIMER6, // High density only; no compare - TIMER7, // High density only; no compare - TIMER8, // High density only + TIMER1, + TIMER2, + TIMER3, + TIMER4, + TIMER5, // High density only + TIMER6, // High density only; no compare + TIMER7, // High density only; no compare + TIMER8, // High density only }; -// timer descriptor +/* timer descriptor */ struct timer_dev { - timer_port *base; - const uint8 rcc_dev_num; - const uint8 nvic_dev_num; - volatile voidFuncPtr handlers[4]; + timer_port *base; + const uint8 rcc_dev_num; + const uint8 nvic_dev_num; + volatile voidFuncPtr handlers[4]; }; extern struct timer_dev timer_dev_table[]; @@ -206,7 +205,7 @@ extern struct timer_dev timer_dev_table[]; * void timer_init(uint32 timer, uint16 prescale) * timer -> {1-4} * prescale -> {1-65535} - * */ + */ void timer_init(uint8, uint16); void timer_disable_all(void); uint16 timer_get_count(uint8); @@ -217,7 +216,8 @@ void timer_set_prescaler(uint8 timer_num, uint16 prescale); void timer_set_reload(uint8 timer_num, uint16 max_reload); void timer_set_mode(uint8 timer_num, uint8 compare_num, uint8 mode); void timer_set_compare_value(uint8 timer_num, uint8 compare_num, uint16 value); -void timer_attach_interrupt(uint8 timer_num, uint8 compare_num, voidFuncPtr handler); +void timer_attach_interrupt(uint8 timer_num, uint8 compare_num, + voidFuncPtr handler); void timer_detach_interrupt(uint8 timer_num, uint8 compare_num); /* Turn on PWM with duty_cycle on the specified channel in timer. diff --git a/libmaple/usart.c b/libmaple/usart.c index ef54ad0..34095f8 100644 --- a/libmaple/usart.c +++ b/libmaple/usart.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,12 +20,12 @@ * 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 usart.c + * @file usart.c * - * @brief USART control routines + * @brief USART control routines */ #include "libmaple.h" @@ -48,55 +48,60 @@ /* usart descriptor table */ struct usart_dev usart_dev_table[] = { - [USART1] = { - .base = (usart_port*)USART1_BASE, - .rcc_dev_num = RCC_USART1, - .nvic_dev_num = NVIC_USART1 - }, - [USART2] = { - .base = (usart_port*)USART2_BASE, - .rcc_dev_num = RCC_USART2, - .nvic_dev_num = NVIC_USART2 - }, - [USART3] = { - .base = (usart_port*)USART3_BASE, - .rcc_dev_num = RCC_USART3, - .nvic_dev_num = NVIC_USART3 - }, - /* - #if NR_USART >= 5 - [UART4] = { + [USART1] = { + .base = (usart_port*)USART1_BASE, + .rcc_dev_num = RCC_USART1, + .nvic_dev_num = NVIC_USART1 + }, + [USART2] = { + .base = (usart_port*)USART2_BASE, + .rcc_dev_num = RCC_USART2, + .nvic_dev_num = NVIC_USART2 + }, + [USART3] = { + .base = (usart_port*)USART3_BASE, + .rcc_dev_num = RCC_USART3, + .nvic_dev_num = NVIC_USART3 + }, + /* + #if NR_USART >= 5 + [UART4] = { .base = (usart_port*)UART4_BASE, .rcc_dev_num = RCC_UART4, .nvic_dev_num = NVIC_UART4 - }, - [UART5] = { + }, + [UART5] = { .base = (usart_port*)UART5_BASE, .rcc_dev_num = RCC_UART5, .nvic_dev_num = NVIC_UART5 - }, - #endif - */ + }, + #endif + */ }; /* usart interrupt handlers */ void USART1_IRQHandler(void) { - rb_insert(&(usart_dev_table[USART1].rb), (uint8)(((usart_port*)(USART1_BASE))->DR)); + rb_insert(&(usart_dev_table[USART1].rb), + (uint8)(((usart_port*)(USART1_BASE))->DR)); } void USART2_IRQHandler(void) { - rb_insert(&(usart_dev_table[USART2].rb), (uint8)(((usart_port*)(USART2_BASE))->DR)); + rb_insert(&(usart_dev_table[USART2].rb), + (uint8)(((usart_port*)(USART2_BASE))->DR)); } void USART3_IRQHandler(void) { - rb_insert(&usart_dev_table[USART3].rb, (uint8)(((usart_port*)(USART3_BASE))->DR)); + rb_insert(&usart_dev_table[USART3].rb, + (uint8)(((usart_port*)(USART3_BASE))->DR)); } #if NR_USART >= 5 void UART4_IRQHandler(void) { - rb_insert(&usart_dev_table[UART4].rb, (uint8)(((usart_port*)(UART4_BASE))->DR)); + rb_insert(&usart_dev_table[UART4].rb, + (uint8)(((usart_port*)(UART4_BASE))->DR)); } void UART5_IRQHandler(void) { - rb_insert(&usart_dev_table[UART5].rb, (uint8)(((usart_port*)(UART5_BASE))->DR)); + rb_insert(&usart_dev_table[UART5].rb, + (uint8)(((usart_port*)(UART5_BASE))->DR)); } #endif @@ -153,15 +158,15 @@ void usart_disable_all() { usart_disable(USART1); usart_disable(USART2); usart_disable(USART3); - #if NR_USART >= 5 +#if NR_USART >= 5 usart_disable(UART4); usart_disable(UART5); - #endif +#endif } /** - * @brief Turn off a USART. - * @param USART to be disabled + * @brief Turn off a USART. + * @param USART to be disabled */ void usart_disable(uint8 usart_num) { usart_port *port = usart_dev_table[usart_num].base; @@ -179,10 +184,10 @@ void usart_disable(uint8 usart_num) { /** - * @brief Print a null terminated string to the specified USART + * @brief Print a null terminated string to the specified USART * - * @param usart_num usart to send on - * @param str string to send + * @param usart_num usart to send on + * @param str string to send */ void usart_putstr(uint8 usart_num, const char* str) { char ch; @@ -193,10 +198,10 @@ void usart_putstr(uint8 usart_num, const char* str) { } /** - * @brief Print an unsigned integer to the specified usart + * @brief Print an unsigned integer to the specified usart * - * @param usart_num usart to send on - * @param val number to print + * @param usart_num usart to send on + * @param val number to print */ void usart_putudec(uint8 usart_num, uint32 val) { char digits[12]; diff --git a/libmaple/usart.h b/libmaple/usart.h index 2bc472f..5c9de68 100644 --- a/libmaple/usart.h +++ b/libmaple/usart.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,10 +20,10 @@ * 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 USART definitions and prototypes + * @brief USART definitions and prototypes */ #ifndef _USART_H_ @@ -39,11 +39,11 @@ extern "C"{ /* usart device numbers */ enum { - USART1, - USART2, - USART3, - UART4, - UART5, + USART1, + USART2, + USART3, + UART4, + UART5, }; /* peripheral register struct */ @@ -59,16 +59,15 @@ typedef struct usart_port { /* usart descriptor */ struct usart_dev { - usart_port *base; - ring_buffer rb; - uint8 rx_buf[64]; - const uint8 rcc_dev_num; - const uint8 nvic_dev_num; + usart_port *base; + ring_buffer rb; + uint8 rx_buf[64]; + const uint8 rcc_dev_num; + const uint8 nvic_dev_num; }; extern struct usart_dev usart_dev_table[]; - /** * @brief send one character on a usart * @param usart_num usart to send on @@ -84,7 +83,6 @@ static inline void usart_putc(uint8 usart_num, uint8 byte) { ; } - /** * @brief read one character from a usart * @param usart_num usart to read from @@ -94,7 +92,6 @@ static inline uint8 usart_getc(uint8 usart_num) { return rb_remove(&usart_dev_table[usart_num].rb); } - /** * @brief return the amount of data available in the rx buffer * @param usart_num which usart to check @@ -104,7 +101,6 @@ static inline uint32 usart_data_available(uint8 usart_num) { return rb_full_count(&usart_dev_table[usart_num].rb); } - /** * @brief removes the contents of the rx fifo * @param usart_num which usart to reset @@ -123,6 +119,4 @@ void usart_putudec(uint8 usart_num, uint32 val); } // extern "C" #endif - -#endif - +#endif _USART_H_ diff --git a/libmaple/usb/README b/libmaple/usb/README index e542dde..f3970b6 100644 --- a/libmaple/usb/README +++ b/libmaple/usb/README @@ -1,9 +1,11 @@ The USB submodule of libmaple is responsible for: - initilizing the usb peripheral, scaling the peripheral clocks appropriately, - enabling the interrupt channels to usb, defining the usb isr, resetting the usb - disc pin (used to tell the host were alive). Additionally, the usb submodule defines - the virtual com port usb applications that is available to all user sketches via Usb.print() - and others. + + Initializing the USB peripheral, scaling the peripheral clocks + appropriately, enabling the interrupt channels to USB, defining + the USB isr, resetting the USB disc pin (used to tell the host + were alive). Additionally, the USB submodule defines the virtual + com port USB applications that is available to all user sketches + via Usb.print() and others. To use it: Call Usb.init() to enable the IRQ channel, configure the clocks, @@ -13,56 +15,78 @@ To use it: Current Status: - Currently, the USB submodule relies on the low level core library provided by ST to access the - usb peripheral registers and implement the usb transfer protocol for control endpoint transfers. - The high level virtual com port application is unfortunately hard to untangle from this low level - dependence, and when a new USB core library is written (to nix ST dependence) changes will likely - have to be made to virtual com application code. Ideally, the new core library should mimick the - form of MyUSB (LUFA), since this library (USB for AVR) is growing in popularity and in example - applications. Additionally, the usb lib here relies on low level hardware functions that were - just ripped out of the bootloader code (for simplicity) but clearly this should be replaced with - direct accesses to functions provided elsewhere in libmaple. + Currently, the USB submodule relies on the low level core library + provided by ST to access the USB peripheral registers and + implement the USB transfer protocol for control endpoint + transfers. The high level virtual com port application is + unfortunately hard to untangle from this low level dependence, and + when a new USB core library is written (to nix ST dependence) + changes will likely have to be made to virtual com application + code. Ideally, the new core library should mimick the form of + MyUSB (LUFA), since this library (USB for AVR) is growing in + popularity and in example applications. Additionally, the USB lib + here relies on low level hardware functions that were just ripped + out of the bootloader code (for simplicity) but clearly this + should be replaced with direct accesses to functions provided + elsewhere in libmaple. - The virtual com port serves two important purposes. 1) is allows serial data transfers between - user sketches an a host computer. 2) is allows the host machine to issue a system reset by - asserting the DTR signal. After reset, Maple will run the DFU bootloader for a few seconds, - during which the user can begin a DFU download operation ('downloads' application binary into - RAM/FLASH). This without this virtual com port, it would be necessary to find an alternative means - to reset the chip in order to enable the bootloader. + The virtual com port serves two important purposes. 1) is allows + serial data transfers between user sketches an a host computer. 2) + is allows the host machine to issue a system reset by asserting + the DTR signal. After reset, Maple will run the DFU bootloader for + a few seconds, during which the user can begin a DFU download + operation ('downloads' application binary into RAM/FLASH). This + without this virtual com port, it would be necessary to find an + alternative means to reset the chip in order to enable the + bootloader. - If you would like to develop your own USB application for whatever reason (uses faster isochronous - enpoints for streaming audio, or implements the USB HID or Mass Storage specs for examples) then - ensure that you leave some hook for resetting Maple remotely in order to spin up the DFU bootloader. - Please make sure to give yourself a unique vendor/product ID pair in your application, as some - operating systems will assign a host-side driver based on these tags. + If you would like to develop your own USB application for whatever + reason (uses faster isochronous enpoints for streaming audio, or + implements the USB HID or Mass Storage specs for examples) then + ensure that you leave some hook for resetting Maple remotely in + order to spin up the DFU bootloader. Please make sure to give + yourself a unique vendor/product ID pair in your application, as + some operating systems will assign a host-side driver based on + these tags. - It would be possible to build a compound usb device, that implements endpoints for both the virtual - COM port as well as some other components (mass sotrage etc.) however this turns out to be a burden - from the host driver side, as windows and *nix handle compound usb devices quite differently. + It would be possible to build a compound USB device, that + implements endpoints for both the virtual COM port as well as some + other components (mass sotrage etc.) however this turns out to be + a burden from the host driver side, as windows and *nix handle + compound USB devices quite differently. - Be mindful that running the usb application isnt "free." The device must respond to periodic bus - activity (every few milliseconds) by servicing an ISR. Therefore the usb application should be disabled - inside of timing critical applications. In order to disconnect the device from the host, the USB_DISC - pin can be asserted (on Maple v1,2,3 this is GPIOC,12). Alternatively, the NVIC can be directly configured - to disable the USB LP/HP IRQ's + Be mindful that running the USB application isnt "free." The + device must respond to periodic bus activity (every few + milliseconds) by servicing an ISR. Therefore the USB application + should be disabled inside of timing critical applications. In + order to disconnect the device from the host, the USB_DISC pin can + be asserted (on Maple v1,2,3 this is GPIOC,12). Alternatively, the + NVIC can be directly configured to disable the USB LP/HP IRQ's - This library should exposed through usb.h, do not include any other files direcly in your application. + This library should exposed through usb.h, do not include any + other files direcly in your application. - The files inside of usb_lib were provided by ST and are subject to their own license, all other files were - written by the LeafLabs team and fall under the MIT license. + The files inside of usb_lib were provided by ST and are subject to + their own license, all other files were written by the LeafLabs + team and fall under the MIT license. Integration with libmaple: - The current usb lib is ported directly from the maple bootloader code, adapted to be a virtual com rather than - a DFU device. That means several functions are redefined locally that could have been pulled from elsewhere - in libmaple. Thus, ths usb module depends absolutely zero on libmaple, it even ensures that clocks are configured - correctly for its operation. + + The current USB lib is ported directly from the maple bootloader + code, adapted to be a virtual com rather than a DFU device. That + means several functions are redefined locally that could have been + pulled from elsewhere in libmaple. Thus, ths USB module depends + absolutely zero on libmaple, it even ensures that clocks are + configured correctly for its operation. Todo: - - write custom low level usb stack to strip out any remaining dependence on ST code - - remove dependence on hardware.c, since any functions here really should have their - own analogues elsewhere inside libmaple - - add a high level usb application library that would allow users to make their own - HID/Mass Storage/Audio/Video devices. + + - write custom low level USB stack to strip out any remaining + dependence on ST code + - remove dependence on hardware.c, since any functions here really + should have their own analogues elsewhere inside libmaple + - add a high level USB application library that would allow users + to make their own HID/Mass Storage/Audio/Video devices. - implement a Usb.link(SerialX) that forces a passthrough the host computer virtual com to SerialX, and utilizes the - line_config commands correctly (sets baud etc) \ No newline at end of file + line_config commands correctly (sets baud etc) diff --git a/libmaple/util.c b/libmaple/util.c index 3325d2b..be29e7e 100644 --- a/libmaple/util.c +++ b/libmaple/util.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,13 +20,13 @@ * 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 util.h + * @file util.h * - * @brief Utility procedures for debugging, mostly an error LED fade and - * messages dumped over a uart for failed asserts. + * @brief Utility procedures for debugging, mostly an error LED fade + * and messages dumped over a uart for failed asserts. */ #include "libmaple.h" @@ -52,14 +52,14 @@ void _fail(const char* file, int line, const char* exp) { /* Turn off ADC */ adc_disable(); - /* Turn off all usarts */ + /* Turn off all usarts */ usart_disable_all(); /* Initialize the error usart */ gpio_set_mode(ERROR_TX_PORT, ERROR_TX_PIN, GPIO_MODE_AF_OUTPUT_PP); usart_init(ERROR_USART_NUM, ERROR_USART_BAUD); - /* Print failed assert message */ + /* Print failed assert message */ usart_putstr(ERROR_USART_NUM, "ERROR: FAILED ASSERT("); usart_putstr(ERROR_USART_NUM, exp); usart_putstr(ERROR_USART_NUM, "): "); @@ -69,43 +69,43 @@ void _fail(const char* file, int line, const char* exp) { usart_putc(ERROR_USART_NUM, '\n'); usart_putc(ERROR_USART_NUM, '\r'); - /* Turn on the error LED */ + /* Turn on the error LED */ gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); - /* Turn the USB interrupt back on so the bootloader keeps on functioning */ + /* Turn the USB interrupt back on so the bootloader keeps on functioning */ nvic_irq_enable(NVIC_INT_USBHP); nvic_irq_enable(NVIC_INT_USBLP); - /* Error fade */ + /* Error fade */ throb(); } void throb(void) { - int32 slope = 1; - uint32 CC = 0x0000; - uint32 TOP_CNT = 0x0200; - uint32 i = 0; - - gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); - /* Error fade */ - while (1) { - if (CC == TOP_CNT) { - slope = -1; - } else if (CC == 0) { - slope = 1; - } - - if (i == TOP_CNT) { - CC += slope; - i = 0; - } - - if (i < CC) { - gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 1); - } else { - gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 0); - } - i++; - } + int32 slope = 1; + uint32 CC = 0x0000; + uint32 TOP_CNT = 0x0200; + uint32 i = 0; + + gpio_set_mode(ERROR_LED_PORT, ERROR_LED_PIN, GPIO_MODE_OUTPUT_PP); + /* Error fade */ + while (1) { + if (CC == TOP_CNT) { + slope = -1; + } else if (CC == 0) { + slope = 1; + } + + if (i == TOP_CNT) { + CC += slope; + i = 0; + } + + if (i < CC) { + gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 1); + } else { + gpio_write_bit(ERROR_LED_PORT, ERROR_LED_PIN, 0); + } + i++; + } } diff --git a/libmaple/util.h b/libmaple/util.h index f5e7e88..2bbd90c 100644 --- a/libmaple/util.h +++ b/libmaple/util.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,7 +20,7 @@ * 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 util.h @@ -41,23 +41,25 @@ #define GET_BITS(x, m, n) ((((uint32)x) << (31 - (n))) >> ((31 - (n)) + (m))) /* Bit-banding macros */ -#define BITBAND_SRAM(a,b) ((BITBAND_SRAM_BASE + (a-BITBAND_SRAM_REF)*32 + (b*4))) // Convert SRAM address -#define BITBAND_PERI(a,b) ((BITBAND_PERI_BASE + (a-BITBAND_PERI_REF)*32 + (b*4))) // Convert PERI address +/* Convert SRAM address */ +#define BITBAND_SRAM(a,b) ((BITBAND_SRAM_BASE+(a-BITBAND_SRAM_REF)*32+(b*4))) +/* Convert PERI address */ +#define BITBAND_PERI(a,b) ((BITBAND_PERI_BASE+(a-BITBAND_PERI_REF)*32+(b*4))) -#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_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) +#define REG_GET(reg) *(volatile uint32*)(reg) -#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 __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 __read(reg) *(volatile uint32*)(reg) +#define __write(reg, value) *(volatile uint32*)(reg) = (value) #define IS_POWER_OF_TWO(v) (v && !(v & (v - 1))) @@ -72,30 +74,31 @@ void throb(void); } // extern "C" #endif - -// Asserts for sanity checks, redefine DEBUG_LEVEL in libmaple.h to compile out -// these checks +/* Asserts for sanity checks, redefine DEBUG_LEVEL in libmaple.h to + * compile out these checks */ #define DEBUG_NONE 0 #define DEBUG_FAULT 1 #define DEBUG_ALL 2 #if DEBUG_LEVEL >= DEBUG_ALL -#define ASSERT(exp) \ - if (exp) \ - {} \ - else \ - _fail(__FILE__, __LINE__, #exp) +#define ASSERT(exp) \ + if (exp) { \ + } else { \ + _fail(__FILE__, __LINE__, #exp); \ + } + #else #define ASSERT(exp) (void)((0)) #endif #if DEBUG_LEVEL >= DEBUG_FAULT -#define ASSERT_FAULT(exp) \ - if (exp) \ - {} \ - else \ - _fail(__FILE__, __LINE__, #exp) +#define ASSERT_FAULT(exp) \ + if (exp) { \ + } else { \ + _fail(__FILE__, __LINE__, #exp); \ + } + #else #define ASSERT_FAULT(exp) (void)((0)) #endif diff --git a/notes/fsmc.txt b/notes/fsmc.txt index b41de60..1f70760 100644 --- a/notes/fsmc.txt +++ b/notes/fsmc.txt @@ -15,14 +15,15 @@ SRAM chip details t_aa (address access) = 55ns -The FSMC nomenclature is very confusing. There are three seperate "banks" -(which I will call "peripheral banks") each of specialized for different types -of external memory (NOR flash, NAND flash, SRAM, etc). We use the one for -"PSRAM" with our SRAM chip; it's bank #1. The SRAM peripheral bank is further -split into 4 "banks" (which I will call "channels") to support multiple -external devices with chip select pins. I think what's going on is that there -are 4 hardware peripherals and many sections of RAM; the docs are confusing -about what's a "block of memeory" and what's an "FSMC block". +The FSMC nomenclature is very confusing. There are three separate +"banks" (which I will call "peripheral banks") each specialized for +different types of external memory (NOR flash, NAND flash, SRAM, +etc). We use the one for "PSRAM" with our SRAM chip; it's bank #1. The +SRAM peripheral bank is further split into 4 "banks" (which I will +call "channels") to support multiple external devices with chip select +pins. I think what's going on is that there are 4 hardware peripherals +and many sections of RAM; the docs are confusing about what's a "block +of memeory" and what's an "FSMC block". Anyways, this all takes place on the AHB memory bus. -- cgit v1.2.3 From 7b72956308b7793defc6bf708ea4dc830573c0a6 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Mon, 27 Sep 2010 03:47:47 -0400 Subject: added notes/coding_standard.txt, more cleanups --- .dir-locals.el | 6 ++ libmaple/usart.h | 2 +- notes/coding_standard.txt | 164 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 .dir-locals.el create mode 100644 notes/coding_standard.txt (limited to 'libmaple') diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..aed97bb --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,6 @@ +((c-mode . ((c-basic-offset . 4) + (indent-tabs-mode . nil) + (tab-width . 50))) ; display tabs badly on purpose + (c++-mode . ((c-basic-offset . 4) + (indent-tabs-mode . nil) + (tab-width . 50)))) ; display tabs badly on purpose \ No newline at end of file diff --git a/libmaple/usart.h b/libmaple/usart.h index 5c9de68..593fb8f 100644 --- a/libmaple/usart.h +++ b/libmaple/usart.h @@ -119,4 +119,4 @@ void usart_putudec(uint8 usart_num, uint32 val); } // extern "C" #endif -#endif _USART_H_ +#endif // _USART_H_ diff --git a/notes/coding_standard.txt b/notes/coding_standard.txt new file mode 100644 index 0000000..bab1e38 --- /dev/null +++ b/notes/coding_standard.txt @@ -0,0 +1,164 @@ +Source code standards for libmaple. + +Do it like this unless there's a really good reason why not. You +being a lazy bastard doesn't count as a good reason. + +The file .dir-locals.el in the libmaple root directory already ensures +that many of these standards are followed by default, if you use emacs +(and not Windows, where it would need to be named _dir_locals.el, and +no way, man). There's also some elisp scattered about this file which +will provide you additional help. + +Vim customizations to do the same thing would be nice! + +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 your or + 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: + + (require 'elide-head) + (setq programming-mode-hooks '(c-mode-hook c++-mode-hook)) + (add-to-list 'elide-head-headers-to-hide + '("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) + (add-hook hook (lambda () (elide-head)))) + +Whitespace +---------- + +- 4 space indents. [Set in .dir-locals.el] + +- Unix newlines. + +- No tab characters. [Set in .dir-locals.el] + +- No trailing whitespace. For help getting this (and no tab + characters) done automatically in Emacs, you can use this: + + http://github.com/mbolivar/code-fascism + + I hear tell you can get something similar in vim; ask Perry, I + guess. + +- Files end in exactly one newline. [The presence of a newline at EOF + is already done by `c-require-final-newline' in recent versions of + emacs.] + +- Exactly two newlines separate source paragraphs. + +- The first line in a function is non-blank. + +Comments +-------- + +- Multi-line comments look like this: + + /* text 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 */ + +- Doxygen comments are newline comments that begin with /** instead. + +- Single-line comments on the same line are // in c or c++. + +- 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... + + 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". + +Braces +------ + +- 1TBS. Nothing more need be said. + + http://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS + +Naming conventions +------------------ + +So 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? + +- Variables: Use underscores to separate words in C identifiers: + + int some_example_name; + + It is strongly advised to do it this way in C++ too, but it's not + [yet] mandatory. + +- Classes: Pascal case. So ThisIsAClassName, but thisIsNot, + this_is_not, and like I said, Dont_You_DareTryANYTHING_STUPID. + +- Functions: C functions are all lowercase, and words are separated by + underscores. C++ method names are camel cased. + +- Structs: pick a style from "Variables" or "Classes" depending on how + you mean it (since it might be either a simple record type, in which + case do like c variables, or you might be faking an object in c, in + which case do like classes). If it's in a typedef, should also + probably put _t at the end, but maybe you won't, and I don't really + feel too strongly about it. + +- Acronyms: The case of letters in an acronym is determined by the + case of the first letter in the acronym. Examples: + + void usb_func() { ... } + + class SomethingUSB { + void usbInit(); + void initUSB(); + }; + + NEVER DO THIS: + + class BadUsb { ... }; // say "GoodUSB" instead + +- Macros and constants: all caps, separated by underscores. + +- foo.h gets ifdef'ed to _FOO_H_. + +Documentation +------------- + +- Document your code, bitches! + +- At least put a doxygen comment with a nonempty @brief for every + source file you add. See the existing ones for examples. + +General Formatting +------------------ + +- Keep it 80-column clean. That means Emacs says the largest column + number=79. If you haven't already, you should turn on column + numbers to help you out: + + (column-number-mode 1) + + You can get more help from lineker-mode. Download it here: + + http://www.helsinki.fi/~sjpaavol/programs/lineker.el + + Then put the file somewhere in your load-path, and + + (require 'lineker) + (dolist (hook programming-mode-hooks) + (add-hook hook (lambda () (lineker-mode 1)))) -- cgit v1.2.3