diff options
author | Michael Hope <michael.hope@linaro.org> | 2010-09-29 20:45:57 +1300 |
---|---|---|
committer | Michael Hope <michael.hope@linaro.org> | 2010-09-29 20:45:57 +1300 |
commit | 6fcd4cd306dbecf56f5b0b506a3c23762d1219fa (patch) | |
tree | 467125eca5a2e6706001cad8e09bc475e58a12d9 | |
parent | 368e4fc1662c2594b2a0908900713a2555a3ed8e (diff) | |
parent | adde11b099ff5dad176e410279d21feac39d2c7e (diff) | |
download | librambutan-6fcd4cd306dbecf56f5b0b506a3c23762d1219fa.tar.gz librambutan-6fcd4cd306dbecf56f5b0b506a3c23762d1219fa.zip |
Merge remote branch 'upstream/master'
67 files changed, 2063 insertions, 1831 deletions
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 @@ -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/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/exc.c b/libmaple/exc.S index a5c67fa..a9f6561 100644 --- a/libmaple/exc.c +++ b/libmaple/exc.S @@ -1,63 +1,61 @@ -
-/* *****************************************************************************
- * 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)
- ;
-}
-
+/* ***************************************************************************** + * 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 + +# 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--> <previous> +# xPSR +# PC +# LR +# r12 +# r3 +# r2 +# r1 +# SP--> r0 + +.text +.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 + + diff --git a/libmaple/exti.c b/libmaple/exti.c index 5575906..acd7c94 100644 --- a/libmaple/exti.c +++ b/libmaple/exti.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,23 +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. - * ****************************************************************************/ - + *****************************************************************************/ /** - * @file exti.c + * @file exti.c * - * @brief External interrupt control routines + * @brief External interrupt control routines */ #include "libmaple.h" #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 +65,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 +111,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 +128,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 +136,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_bits(EXTI_IMR, BIT(channel)); + __clear_bits(EXTI_FTSR, BIT(channel)); + __clear_bits(EXTI_RTSR, BIT(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; - } + nvic_irq_disable(exti_channels[channel].irq_line); - /* Clear handler function pointer */ - exti_handlers[channel] = 0; + exti_channels[channel].handler = NULL; } diff --git a/libmaple/exti.h b/libmaple/exti.h index 2832e24..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 @@ -100,12 +107,16 @@ #define NR_EXTI_CHANNELS 16 #define NR_EXTI_PORTS NR_GPIO_PORTS // board specific -#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_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 +#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) @@ -113,10 +124,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 +149,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/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 d49f95a..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 @@ -45,5 +45,9 @@ typedef void (*voidFuncPtr)(void); #define __io volatile +#ifndef NULL +#define NULL 0 +#endif + #endif diff --git a/libmaple/nvic.c b/libmaple/nvic.c index 60e7eac..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,36 +33,25 @@ #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) { - 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)); } /** - * @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) { - 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) { @@ -78,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 9e81a0e..e8ca22d 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 @@ -35,8 +35,6 @@ extern "C"{ #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,24 +55,33 @@ extern "C"{ #define NVIC_VectTab_FLASH ((u32)0x08000000) 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, }; -#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); 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/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/spi.c b/libmaple/spi.c index 68855a5..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,82 +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; - ASSERT(spi_num == 1 || spi_num == 2); + 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)) + ; - spi->DR = data; + spi->DR = data; - while (!(spi->SR & SR_TXE) || - (spi->SR & SR_BSY)) - ; + 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; - - ASSERT(spi_num == 1 || spi_num == 2); - spi = (spi_num == 1) ? (SPI*)SPI1_BASE : (SPI*)SPI2_BASE; - - if (!len) { - return 0; - } - - while (i < len) { - spi->DR = buf[i]; - while (!(spi->SR & SR_TXE) || - (spi->SR & SR_BSY) || - !(spi->SR & SR_RXNE)) - ; - rc = spi->DR; - i++; - } - return 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; + + if (!len) { + return 0; + } + + while (i < len) { + while (!(spi->SR & SR_TXE)) + ; + + spi->DR = buf[i]; + + while (!(spi->SR & SR_RXNE)) + ; + + 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 <sys/stat.h> @@ -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..593fb8f 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 a747948..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, "): "); @@ -68,14 +68,25 @@ 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 */ + + /* 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 */ + 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) { diff --git a/libmaple/util.h b/libmaple/util.h index 63e305d..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 @@ -34,30 +34,32 @@ #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 */ #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))) @@ -66,35 +68,37 @@ extern "C"{ #endif void _fail(const char*, int, const char*); +void throb(void); #ifdef __cplusplus } // extern "C" #endif - -// Asserts for sanity checks, redefine DEBUG_LEVEL in libmaple.h to compile out -// these checks +/* 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/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)))) 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. diff --git a/support/ld/maple/jtag.ld b/support/ld/maple/jtag.ld index 8c5ff49..435e3f0 100644 --- a/support/ld/maple/jtag.ld +++ b/support/ld/maple/jtag.ld @@ -8,8 +8,8 @@ /* Define memory spaces. */
MEMORY
{
- ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 17K
- rom (rx) : ORIGIN = 0x08005000, LENGTH = 108K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
}
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
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 $< diff --git a/support/scripts/reset.py b/support/scripts/reset.py index 9be5607..ad26d10 100755 --- a/support/scripts/reset.py +++ b/support/scripts/reset.py @@ -3,6 +3,7 @@ import serial import os import sys +import time from struct import pack def get_maple_device_path(file_prefix): @@ -68,14 +69,20 @@ try: # try to toggle DTR/RTS (old scheme) ser.setRTS(0) + time.sleep(0.01) ser.setDTR(0) + time.sleep(0.01) ser.setDTR(1) + time.sleep(0.01) ser.setDTR(0) # try magic number ser.setRTS(1) + time.sleep(0.01) ser.setDTR(1) + time.sleep(0.01) ser.setDTR(0) + time.sleep(0.01) ser.write("1EAF") # ok we're done here diff --git a/wirish/HardwareTimer.cpp b/wirish/HardwareTimer.cpp index 99863c1..6fbad8b 100644 --- a/wirish/HardwareTimer.cpp +++ b/wirish/HardwareTimer.cpp @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Bryan Newbold. @@ -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 wirish timer class to manage the four 16-bit timer peripherals @@ -43,99 +43,127 @@ HardwareTimer::HardwareTimer(uint8 timerNum) { void HardwareTimer::resume(void) { timer_resume(this->timerNum); } + void HardwareTimer::pause(void) { timer_pause(this->timerNum); } + void HardwareTimer::setPrescaleFactor(uint16 factor) { // The prescaler register is zero-indexed timer_set_prescaler(this->timerNum, factor-1); } + void HardwareTimer::setOverflow(uint16 val) { this->overflow = val; timer_set_reload(this->timerNum, val); } -void HardwareTimer::setCount(uint16 val) { - if(val > this->overflow) + +void HardwareTimer::setCount(uint16 val) { + if(val > this->overflow) { val = this->overflow; + } timer_set_count(this->timerNum, val); } + uint16 HardwareTimer::getCount(void) { return timer_get_count(this->timerNum); } -// This function will set the prescaler and overflow to get -// a period of the given length with the most resolution; -// the return value is the overflow value and thus the largest -// value that can be set as a compare. +/* This function will set the prescaler and overflow to get a period + * of the given length with the most resolution; the return value is + * the overflow value and thus the largest value that can be set as a + * compare. */ uint16 HardwareTimer::setPeriod(uint32 microseconds) { // XXX: 72MHz shouldn't be hard coded in here... global define? - + // Not the best way to handle this edge case? if(!microseconds) { setPrescaleFactor(1); setOverflow(1); return this->overflow; } + // With a prescale factor of 1, there are 72counts/ms uint16 ps = ((microseconds*72)/65536) + 1; setPrescaleFactor(ps); + // Finally, this overflow will always be less than 65536 setOverflow(((microseconds*72)/ps) - 1); - return this->overflow; + return this->overflow; } + void HardwareTimer::setChannel1Mode(uint8 mode) { timer_set_mode(this->timerNum,1,mode); } + void HardwareTimer::setChannel2Mode(uint8 mode) { timer_set_mode(this->timerNum,2,mode); } + void HardwareTimer::setChannel3Mode(uint8 mode) { timer_set_mode(this->timerNum,3,mode); } + void HardwareTimer::setChannel4Mode(uint8 mode) { timer_set_mode(this->timerNum,4,mode); } + void HardwareTimer::setCompare1(uint16 val) { - if(val > this->overflow) + if(val > this->overflow) { val = this->overflow; + } timer_set_compare_value(this->timerNum,1,val); } + void HardwareTimer::setCompare2(uint16 val) { - if(val > this->overflow) + if(val > this->overflow) { val = this->overflow; + } timer_set_compare_value(this->timerNum,2,val); } + void HardwareTimer::setCompare3(uint16 val) { - if(val > this->overflow) + if(val > this->overflow) { val = this->overflow; + } timer_set_compare_value(this->timerNum,3,val); } + void HardwareTimer::setCompare4(uint16 val) { - if(val > this->overflow) + if(val > this->overflow) { val = this->overflow; + } timer_set_compare_value(this->timerNum,4,val); } + void HardwareTimer::attachCompare1Interrupt(voidFuncPtr handler) { timer_attach_interrupt(this->timerNum,1,handler); } + void HardwareTimer::attachCompare2Interrupt(voidFuncPtr handler) { timer_attach_interrupt(this->timerNum,2,handler); } + void HardwareTimer::attachCompare3Interrupt(voidFuncPtr handler) { timer_attach_interrupt(this->timerNum,3,handler); } + void HardwareTimer::attachCompare4Interrupt(voidFuncPtr handler) { timer_attach_interrupt(this->timerNum,4,handler); } + void HardwareTimer::detachCompare1Interrupt(void) { timer_detach_interrupt(this->timerNum,1); } + void HardwareTimer::detachCompare2Interrupt(void) { timer_detach_interrupt(this->timerNum,2); } + void HardwareTimer::detachCompare3Interrupt(void) { timer_detach_interrupt(this->timerNum,3); } + void HardwareTimer::detachCompare4Interrupt(void) { timer_detach_interrupt(this->timerNum,4); } diff --git a/wirish/HardwareTimer.h b/wirish/HardwareTimer.h index aa48718..c6e11c8 100644 --- a/wirish/HardwareTimer.h +++ b/wirish/HardwareTimer.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Bryan Newbold. @@ -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 wirish timer class to manage the four 16-bit timer peripherals @@ -30,38 +30,38 @@ #define _TIMER_H_ class HardwareTimer { - private: - uint16 overflow; - uint8 timerNum; + private: + uint16 overflow; + uint8 timerNum; - public: - HardwareTimer(uint8 timer_num); + public: + HardwareTimer(uint8 timer_num); - void pause(void); - void resume(void); - void setPrescaleFactor(uint16 factor); - void setOverflow(uint16 val); // truncates to overflow - void setCount(uint16 val); // truncates to overflow - uint16 getCount(void); + void pause(void); + void resume(void); + void setPrescaleFactor(uint16 factor); + void setOverflow(uint16 val); // truncates to overflow + void setCount(uint16 val); // truncates to overflow + uint16 getCount(void); - // tries to set prescaler and overflow wisely; returns overflow - uint16 setPeriod(uint32 microseconds); - void setChannel1Mode(uint8 mode); - void setChannel2Mode(uint8 mode); - void setChannel3Mode(uint8 mode); - void setChannel4Mode(uint8 mode); - void setCompare1(uint16 val); // truncates to overflow - void setCompare2(uint16 val); // truncates to overflow - void setCompare3(uint16 val); // truncates to overflow - void setCompare4(uint16 val); // truncates to overflow - void attachCompare1Interrupt(voidFuncPtr handler); - void attachCompare2Interrupt(voidFuncPtr handler); - void attachCompare3Interrupt(voidFuncPtr handler); - void attachCompare4Interrupt(voidFuncPtr handler); - void detachCompare1Interrupt(void); - void detachCompare2Interrupt(void); - void detachCompare3Interrupt(void); - void detachCompare4Interrupt(void); + // tries to set prescaler and overflow wisely; returns overflow + uint16 setPeriod(uint32 microseconds); + void setChannel1Mode(uint8 mode); + void setChannel2Mode(uint8 mode); + void setChannel3Mode(uint8 mode); + void setChannel4Mode(uint8 mode); + void setCompare1(uint16 val); // truncates to overflow + void setCompare2(uint16 val); // truncates to overflow + void setCompare3(uint16 val); // truncates to overflow + void setCompare4(uint16 val); // truncates to overflow + void attachCompare1Interrupt(voidFuncPtr handler); + void attachCompare2Interrupt(voidFuncPtr handler); + void attachCompare3Interrupt(voidFuncPtr handler); + void attachCompare4Interrupt(voidFuncPtr handler); + void detachCompare1Interrupt(void); + void detachCompare2Interrupt(void); + void detachCompare3Interrupt(void); + void detachCompare4Interrupt(void); }; extern HardwareTimer Timer1; diff --git a/wirish/Print.cpp b/wirish/Print.cpp index 9baa757..c66ca61 100644 --- a/wirish/Print.cpp +++ b/wirish/Print.cpp @@ -1,213 +1,190 @@ /* - Print.cpp - Base class that provides print() and println() - Copyright (c) 2008 David A. Mellis. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified 23 November 2006 by David A. Mellis + * Print.cpp - Base class that provides print() and println() + * Copyright (c) 2008 David A. Mellis. All right reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * Modified 23 November 2006 by David A. Mellis */ #include "wirish.h" #include "Print.h" -// Public Methods ////////////////////////////////////////////////////////////// - -/* default implementation: may be overridden */ -void Print::write(const char *str) -{ - while (*str) - write(*str++); -} - -/* default implementation: may be overridden */ -void Print::write(void *buffer, uint32 size) -{ - uint8 *ch = (uint8*)buffer; - while (size--) { - write(*ch++); - } -} +//------------------------------ Public Methods ------------------------------- -void Print::print(uint8 b) -{ - this->write(b); +void Print::write(const char *str) { + while (*str) + write(*str++); } -void Print::print(char c) -{ - print((byte) c); +void Print::write(void *buffer, uint32 size) { + uint8 *ch = (uint8*)buffer; + while (size--) { + write(*ch++); + } } -void Print::print(const char str[]) -{ - write(str); +void Print::print(uint8 b) { + this->write(b); } -void Print::print(int n) -{ - print((long) n); +void Print::print(char c) { + print((byte) c); } -void Print::print(unsigned int n) -{ - print((unsigned long) n); +void Print::print(const char str[]) { + write(str); } -void Print::print(long n) -{ - if (n < 0) { - print('-'); - n = -n; - } - printNumber(n, 10); +void Print::print(int n) { + print((long) n); } -void Print::print(unsigned long n) -{ - printNumber(n, 10); +void Print::print(unsigned int n) { + print((unsigned long) n); } -void Print::print(long n, int base) -{ - if (base == 0) - print((char) n); - else if (base == 10) - print(n); - else - printNumber(n, base); +void Print::print(long n) { + if (n < 0) { + print('-'); + n = -n; + } + printNumber(n, 10); } -void Print::print(double n) -{ - printFloat(n, 2); +void Print::print(unsigned long n) { + printNumber(n, 10); } -void Print::println(void) -{ - print('\r'); - print('\n'); +void Print::print(long n, int base) { + if (base == 0) { + print((char) n); + } else if (base == 10) { + print(n); + } else { + printNumber(n, base); + } } -void Print::println(char c) -{ - print(c); - println(); +void Print::print(double n) { + printFloat(n, 2); } -void Print::println(const char c[]) -{ - print(c); - println(); +void Print::println(void) { + print('\r'); + print('\n'); } -void Print::println(uint8 b) -{ - print(b); - println(); +void Print::println(char c) { + print(c); + println(); } -void Print::println(int n) -{ - print(n); - println(); +void Print::println(const char c[]) { + print(c); + println(); } -void Print::println(unsigned int n) -{ - print(n); - println(); +void Print::println(uint8 b) { + print(b); + println(); } -void Print::println(long n) -{ - print(n); - println(); +void Print::println(int n) { + print(n); + println(); } -void Print::println(unsigned long n) -{ - print(n); - println(); +void Print::println(unsigned int n) { + print(n); + println(); } -void Print::println(long n, int base) -{ - print(n, base); - println(); +void Print::println(long n) { + print(n); + println(); } -void Print::println(double n) -{ - print(n); - println(); +void Print::println(unsigned long n) { + print(n); + println(); } -// Private Methods ///////////////////////////////////////////////////////////// - -void Print::printNumber(unsigned long n, uint8 base) -{ - unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. - unsigned long i = 0; - - if (n == 0) { - print('0'); - return; - } - - while (n > 0) { - buf[i++] = n % base; - n /= base; - } - - for (; i > 0; i--) - print((char) (buf[i - 1] < 10 ? - '0' + buf[i - 1] : - 'A' + buf[i - 1] - 10)); +void Print::println(long n, int base) { + print(n, base); + println(); } -void Print::printFloat(double number, uint8 digits) -{ - // Handle negative numbers - if (number < 0.0) - { - print('-'); - number = -number; - } - - // Round correctly so that print(1.999, 2) prints as "2.00" - double rounding = 0.5; - for (uint8 i=0; i<digits; ++i) - rounding /= 10.0; - - number += rounding; - - // Extract the integer part of the number and print it - unsigned long int_part = (unsigned long)number; - double remainder = number - (double)int_part; - print(int_part); - - // Print the decimal point, but only if there are digits beyond - if (digits > 0) - print("."); - - // Extract digits from the remainder one at a time - while (digits-- > 0) - { - remainder *= 10.0; - int toPrint = int(remainder); - print(toPrint); - remainder -= toPrint; - } +void Print::println(double n) { + print(n); + println(); +} + +//------------------------------ Private Methods ------------------------------ + +void Print::printNumber(unsigned long n, uint8 base) { + unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. + unsigned long i = 0; + + if (n == 0) { + print('0'); + return; + } + + while (n > 0) { + buf[i++] = n % base; + n /= base; + } + + for (; i > 0; i--) + print((char) (buf[i - 1] < 10 ? + '0' + buf[i - 1] : + 'A' + buf[i - 1] - 10)); +} + +void Print::printFloat(double number, uint8 digits) { + // Handle negative numbers + if (number < 0.0) { + print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8 i=0; i<digits; ++i) { + rounding /= 10.0; + } + + number += rounding; + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long)number; + double remainder = number - (double)int_part; + print(int_part); + + // Print the decimal point, but only if there are digits beyond + if (digits > 0) { + print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) { + remainder *= 10.0; + int toPrint = int(remainder); + print(toPrint); + remainder -= toPrint; + } } diff --git a/wirish/Print.h b/wirish/Print.h index 9c03978..dc21183 100644 --- a/wirish/Print.h +++ b/wirish/Print.h @@ -1,21 +1,22 @@ /* - Print.h - Base class that provides print() and println() - Copyright (c) 2008 David A. Mellis. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Print.h - Base class that provides print() and println() + * Copyright (c) 2008 David A. Mellis. All right reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA. + */ #ifndef Print_h #define Print_h @@ -31,10 +32,10 @@ class Print { - private: + private: void printNumber(unsigned long, uint8); void printFloat(double, uint8); - public: + public: virtual void write(uint8) = 0; virtual void write(const char *str); virtual void write(void *, uint32); diff --git a/wirish/WProgram.h b/wirish/WProgram.h index 9143991..36984ff 100644 --- a/wirish/WProgram.h +++ b/wirish/WProgram.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 LeafLabs LLC. @@ -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 "wirish.h" diff --git a/wirish/bits.h b/wirish/bits.h index 7ebea80..7b51e5e 100644 --- a/wirish/bits.h +++ b/wirish/bits.h @@ -1,23 +1,23 @@ /*
- Part of Arduino - http://www.arduino.cc/
-
- Copyright (c) 2005-2006 David A. Mellis
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General
- Public License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-*/
+ * Part of Arduino - http://www.arduino.cc/
+ *
+ * Copyright (c) 2005-2006 David A. Mellis
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
// BIT DEFINITION
diff --git a/wirish/boards.h b/wirish/boards.h index 03d0b0e..eed3e26 100644 --- a/wirish/boards.h +++ b/wirish/boards.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Bryan Newbold. @@ -20,12 +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. - * ****************************************************************************/ + *****************************************************************************/ -// This file contains BOARD-specific pin mapping tables. To add a new board -// type, copy the "BOARD_maple" section below and edit it as needed, then -// update your build toolchain with a new "BOARD" type. This must match the -// seperate MCU type (which determines the ../libmaple configuration). +/* This file contains board-specific pin mapping tables. To add a new board + * type, copy the "BOARD_maple" section below and edit it as needed, then + * update your build toolchain with a new "BOARD" type. This must match the + * separate MCU type (which determines the ../libmaple configuration). + */ #ifndef _BOARDS_H_ #define _BOARDS_H_ @@ -36,10 +37,10 @@ #include "exti.h" #ifdef __cplusplus -extern "C"{ +extern "C" { #endif -// Set of all possible digital pin names; not all boards have all these +/* Set of all possible digital pin names; not all boards have all these */ enum { D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, @@ -50,7 +51,7 @@ enum { D92, D93, D94, D95, D96, D97, D98, D99, D100, D101, D102, D103, D104, D105, D106, D107, D108, D109, D110, D111, }; -// Set of all possible analog pin names; not all boards have all these +/* Set of all possible analog pin names; not all boards have all these */ enum { ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15, ADC16, ADC17, ADC18, ADC19, ADC20, }; @@ -58,90 +59,111 @@ enum { #define ADC_INVALID 0xFFFFFFFF #define TIMER_INVALID (TimerCCR)0xFFFFFFFF -// Types used for the tables below +/* Types used for the tables below */ typedef struct PinMapping { GPIO_Port *port; uint32 pin; uint32 adc; TimerCCR timer_channel; + uint32 exti_port; } PinMapping; -typedef struct ExtiInfo { - uint8 channel; - uint8 port; -} ExtiInfo; - -// LeafLabs Maple rev3, rev4 +/* LeafLabs Maple rev3, rev4 */ #ifdef BOARD_maple #define CYCLES_PER_MICROSECOND 72 #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 - /* 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 - /* 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) - }; + /* D0/PA3 */ + {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA}, + /* D1/PA2 */ + {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA}, + /* D2/PA0 */ + {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA}, + /* D3/PA1 */ + {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA}, + /* D4/PB5 */ + {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, + /* D5/PB6 */ + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB}, + /* D6/PA8 */ + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA}, + /* D7/PA9 */ + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA}, + /* D8/PA10 */ + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA}, + /* D9/PB7 */ + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB}, + /* D10/PA4 */ + {GPIOA_BASE, 4, ADC4, TIMER_INVALID, EXTI_CONFIG_PORTA}, + /* D11/PA7 */ + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA}, + /* D12/PA6 */ + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA}, + /* D13/PA5 */ + {GPIOA_BASE, 5, ADC5, TIMER_INVALID, EXTI_CONFIG_PORTA}, + /* D14/PB8 */ + {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB}, - 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 + /* Little header */ + + /* D15/PC0 */ + {GPIOC_BASE, 0, ADC10, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D16/PC1 */ + {GPIOC_BASE, 1, ADC11, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D17/PC2 */ + {GPIOC_BASE, 2, ADC12, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D18/PC3 */ + {GPIOC_BASE, 3, ADC13, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D19/PC4 */ + {GPIOC_BASE, 4, ADC14, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D20/PC5 */ + {GPIOC_BASE, 5, ADC15, TIMER_INVALID, EXTI_CONFIG_PORTC}, + + /* External header */ + + /* D21/PC13 */ + {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D22/PC14 */ + {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D23/PC15 */ + {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D24/PB9 */ + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB}, + /* D25/PD2 */ + {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTD}, + /* D26/PC10 */ + {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D27/PB0 */ + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB}, + /* D28/PB1 */ + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB}, + /* D29/PB10 */ + {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, + /* D30/PB11 */ + {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, + /* D31/PB12 */ + {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, + /* D32/PB13 */ + {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, + /* D33/PB14 */ + {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, + /* D34/PB15 */ + {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTB}, + /* D35/PC6 */ + {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D36/PC7 */ + {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* D37/PC8 */ + {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC}, + /* PC9 (BUT) */ + {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID, EXTI_CONFIG_PORTC} }; #endif -// LeafLabs Maple Native (prototype) +/* LeafLabs Maple Native (prototype) */ #ifdef BOARD_maple_native #define CYCLES_PER_MICROSECOND 72 @@ -149,65 +171,122 @@ typedef struct ExtiInfo { // TODO: 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 + /* D0/PA3 */ + {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR}, + /* D1/PA2 */ + {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR}, + /* D2/PA0 */ + {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR}, + /* D3/PA1 */ + {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR}, + /* D4/PB5 */ + {GPIOB_BASE, 5, ADC_INVALID, TIMER_INVALID}, + /* D5/PB6 */ + {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR}, + /* D6/PA8 */ + {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR}, + /* D7/PA9 */ + {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR}, + /* D8/PA10 */ + {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR}, + /* D9/PB7 */ + {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR}, + /* D10/PA4 */ + {GPIOA_BASE, 4, ADC4, TIMER_INVALID}, + /* D11/PA7 */ + {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR}, + /* D12/PA6 */ + {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR}, + /* D13/PA5 */ + {GPIOA_BASE, 5, ADC5, TIMER_INVALID}, + /* D14/PB8 */ + {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR}, + /* 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 + + /* D15/PC0 */ + {GPIOC_BASE, 0, ADC10, TIMER_INVALID}, + /* D16/PC1 */ + {GPIOC_BASE, 1, ADC11, TIMER_INVALID}, + /* D17/PC2 */ + {GPIOC_BASE, 2, ADC12, TIMER_INVALID}, + /* D18/PC3 */ + {GPIOC_BASE, 3, ADC13, TIMER_INVALID}, + /* D19/PC4 */ + {GPIOC_BASE, 4, ADC14, TIMER_INVALID}, + /* D20/PC5 */ + {GPIOC_BASE, 5, ADC15, TIMER_INVALID}, + /* 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) + + /* D21/PC13 */ + {GPIOC_BASE, 13, ADC_INVALID, TIMER_INVALID}, + /* D22/PC14 */ + {GPIOC_BASE, 14, ADC_INVALID, TIMER_INVALID}, + /* D23/PC15 */ + {GPIOC_BASE, 15, ADC_INVALID, TIMER_INVALID}, + /* D24/PB9 */ + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR}, + /* D25/PD2 */ + {GPIOD_BASE, 2, ADC_INVALID, TIMER_INVALID}, + /* D26/PC10 */ + {GPIOC_BASE, 10, ADC_INVALID, TIMER_INVALID}, + /* D27/PB0 */ + {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR}, + /* D28/PB1 */ + {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR}, + /* D29/PB10 */ + {GPIOB_BASE, 10, ADC_INVALID, TIMER_INVALID}, + /* D30/PB11 */ + {GPIOB_BASE, 11, ADC_INVALID, TIMER_INVALID}, + /* D31/PB12 */ + {GPIOB_BASE, 12, ADC_INVALID, TIMER_INVALID}, + /* D32/PB13 */ + {GPIOB_BASE, 13, ADC_INVALID, TIMER_INVALID}, + /* D33/PB14 */ + {GPIOB_BASE, 14, ADC_INVALID, TIMER_INVALID}, + /* D34/PB15 */ + {GPIOB_BASE, 15, ADC_INVALID, TIMER_INVALID}, + /* D35/PC6 */ + {GPIOC_BASE, 6, ADC_INVALID, TIMER_INVALID}, + /* D36/PC7 */ + {GPIOC_BASE, 7, ADC_INVALID, TIMER_INVALID}, + /* D37/PC8 */ + {GPIOC_BASE, 8, ADC_INVALID, TIMER_INVALID}, + /* PC9 (BUT) */ + {GPIOC_BASE, 9, ADC_INVALID, TIMER_INVALID} }; - static __attribute__ ((unused)) ExtiInfo PIN_TO_EXTI_CHANNEL[NR_GPIO_PINS] = + 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 + /* D0/PA3 */ + {EXTI3, EXTI_CONFIG_PORTA}, + /* D1/PA2 */ + {EXTI2, EXTI_CONFIG_PORTA}, + /* D2/PA0 */ + {EXTI0, EXTI_CONFIG_PORTA}, + /* D3/PA1 */ + {EXTI1, EXTI_CONFIG_PORTA}, + /* D4/PB5 */ + {EXTI5, EXTI_CONFIG_PORTB}, + /* D5/PB6 */ + {EXTI6, EXTI_CONFIG_PORTB}, + /* D6/PA8 */ + {EXTI8, EXTI_CONFIG_PORTA}, + /* D7/PA9 */ + {EXTI9, EXTI_CONFIG_PORTA}, + /* D8/PA10 */ + {EXTI10, EXTI_CONFIG_PORTA}, + /* D9/PB7 */ + {EXTI7, EXTI_CONFIG_PORTB}, + /* D10/PA4 */ + {EXTI4, EXTI_CONFIG_PORTA}, + /* D11/PA7 */ + {EXTI7, EXTI_CONFIG_PORTA}, + /* D12/PA6 */ + {EXTI6, EXTI_CONFIG_PORTA}, + /* D13/PA5 */ + {EXTI5, EXTI_CONFIG_PORTA}, }; #endif diff --git a/wirish/comm/HardwareSPI.cpp b/wirish/comm/HardwareSPI.cpp index 5f42db7..20090f5 100644 --- a/wirish/comm/HardwareSPI.cpp +++ b/wirish/comm/HardwareSPI.cpp @@ -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 HardwareSPI "wiring-like" api for SPI @@ -52,14 +52,14 @@ #include "HardwareSPI.h" static const uint32 prescaleFactors[MAX_SPI_FREQS] = { - SPI_PRESCALE_2, // SPI_18MHZ - SPI_PRESCALE_4, // SPI_9MHZ - SPI_PRESCALE_8, // SPI_4_5MHZ - SPI_PRESCALE_16, // SPI_2_25MHZ - SPI_PRESCALE_32, // SPI_1_125MHZ - SPI_PRESCALE_64, // SPI_562_500KHZ - SPI_PRESCALE_128, // SPI_281_250KHZ - SPI_PRESCALE_256, // SPI_140_625KHZ + SPI_PRESCALE_2, // SPI_18MHZ + SPI_PRESCALE_4, // SPI_9MHZ + SPI_PRESCALE_8, // SPI_4_5MHZ + SPI_PRESCALE_16, // SPI_2_25MHZ + SPI_PRESCALE_32, // SPI_1_125MHZ + SPI_PRESCALE_64, // SPI_562_500KHZ + SPI_PRESCALE_128, // SPI_281_250KHZ + SPI_PRESCALE_256, // SPI_140_625KHZ }; /** @@ -78,37 +78,38 @@ static const uint32 prescaleFactors[MAX_SPI_FREQS] = { * @param mode SPI standard CPOL and CPHA levels */ void HardwareSPI::begin(SPIFrequency freq, uint32 endianness, uint32 mode) { - uint32 spi_num = this->spi_num; - uint32 prescale; - - if ((freq >= MAX_SPI_FREQS) || - !((endianness == LSBFIRST) || - (endianness == MSBFIRST)) || - (mode >= 4)) { - return; - } - - if (spi_num == 1) { - /* SPI1 is too fast for 140625 */ - if (freq == SPI_140_625KHZ) { - return; - } - - /* Turn off PWM on shared pins */ - timer_set_mode(TIMER3, 2, TIMER_DISABLED); - timer_set_mode(TIMER3, 1, TIMER_DISABLED); - } - - endianness = (endianness == LSBFIRST) ? SPI_LSBFIRST : SPI_MSBFIRST; - prescale = (spi_num == 1) ? prescaleFactors[freq + 1] : prescaleFactors[freq]; - - spi_init(spi_num, prescale, endianness, 0); + uint32 spi_num = this->spi_num; + uint32 prescale; + + if ((freq >= MAX_SPI_FREQS) || + !((endianness == LSBFIRST) || + (endianness == MSBFIRST)) || + (mode >= 4)) { + return; + } + + if (spi_num == 1) { + /* SPI1 is too fast for 140625 */ + if (freq == SPI_140_625KHZ) { + return; + } + + /* Turn off PWM on shared pins */ + timer_set_mode(TIMER3, 2, TIMER_DISABLED); + timer_set_mode(TIMER3, 1, TIMER_DISABLED); + } + + endianness = (endianness == LSBFIRST) ? SPI_LSBFIRST : SPI_MSBFIRST; + prescale = (spi_num == 1) ? + prescaleFactors[freq + 1] : + prescaleFactors[freq]; + + spi_init(spi_num, prescale, endianness, mode); } /** - * @brief Initialize a SPI peripheral with a default speed of 1.125 MHZ, MSBFIRST, - * mode 0 - * @param mode SPI standard CPOL and CPHA levels + * @brief Initialize a SPI peripheral with a default speed of 1.125 + * MHZ, MSBFIRST, mode 0 */ void HardwareSPI::begin(void) { begin(SPI_1_125MHZ, MSBFIRST, 0); @@ -126,7 +127,6 @@ uint8 HardwareSPI::send(uint8 *buf, uint32 len) { return spi_tx(this->spi_num, buf, len); } - /** * @brief read a byte from the spi peripheral * @return byte in the buffer diff --git a/wirish/comm/HardwareSPI.h b/wirish/comm/HardwareSPI.h index e606c0c..03d1ea1 100644 --- a/wirish/comm/HardwareSPI.h +++ b/wirish/comm/HardwareSPI.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 HardwareSPI definitions @@ -30,28 +30,28 @@ #define _HARDWARESPI_H_ typedef enum SPIFrequency { - SPI_18MHZ = 0, - SPI_9MHZ = 1, - SPI_4_5MHZ = 2, - SPI_2_25MHZ = 3, - SPI_1_125MHZ = 4, - SPI_562_500KHZ = 5, - SPI_281_250KHZ = 6, - SPI_140_625KHZ = 7, - MAX_SPI_FREQS = 8, + SPI_18MHZ = 0, + SPI_9MHZ = 1, + SPI_4_5MHZ = 2, + SPI_2_25MHZ = 3, + SPI_1_125MHZ = 4, + SPI_562_500KHZ = 5, + SPI_281_250KHZ = 6, + SPI_140_625KHZ = 7, + MAX_SPI_FREQS = 8, } SPIFrequency; class HardwareSPI { - private: - uint32 spi_num; + private: + uint32 spi_num; - public: - HardwareSPI(uint32 spi_num); - void begin(void); - void begin(SPIFrequency freq, uint32 endianness, uint32 mode); - uint8 send(uint8 data); - uint8 send(uint8 *data, uint32 length); - uint8 recv(void); + public: + HardwareSPI(uint32 spi_num); + void begin(void); + void begin(SPIFrequency freq, uint32 endianness, uint32 mode); + uint8 send(uint8 data); + uint8 send(uint8 *data, uint32 length); + uint8 recv(void); }; #endif diff --git a/wirish/comm/HardwareSerial.cpp b/wirish/comm/HardwareSerial.cpp index 902b160..425c610 100644 --- a/wirish/comm/HardwareSerial.cpp +++ b/wirish/comm/HardwareSerial.cpp @@ -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 HardwareSerial.cpp + * @file HardwareSerial.cpp * - * @brief Wiring-like serial api + * @brief Wiring-like serial api */ #include "wirish.h" @@ -68,18 +68,18 @@ void HardwareSerial::write(unsigned char ch) { } void HardwareSerial::begin(uint32 baud) { - if (baud > max_baud) { - return; - } + if (baud > max_baud) { + return; + } - gpio_set_mode(gpio_port, tx_pin, GPIO_MODE_AF_OUTPUT_PP); - gpio_set_mode(gpio_port, rx_pin, GPIO_MODE_INPUT_FLOATING); + gpio_set_mode(gpio_port, tx_pin, GPIO_MODE_AF_OUTPUT_PP); + gpio_set_mode(gpio_port, rx_pin, GPIO_MODE_INPUT_FLOATING); - if ((usart_num == USART1) || - (usart_num == USART2)) { - /* turn off any pwm if there's a conflict on this usart */ - timer_set_mode(timer_num, compare_num, TIMER_DISABLED); - } + if ((usart_num == USART1) || + (usart_num == USART2)) { + /* turn off any pwm if there's a conflict on this usart */ + timer_set_mode(timer_num, compare_num, TIMER_DISABLED); + } usart_init(usart_num, baud); } diff --git a/wirish/comm/HardwareSerial.h b/wirish/comm/HardwareSerial.h index df8d7bf..17be49f 100644 --- a/wirish/comm/HardwareSerial.h +++ b/wirish/comm/HardwareSerial.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 HardwareSerial.h + * @file HardwareSerial.h * - * @brief + * @brief Wirish interface to hardware serial communications. */ #ifndef _HARDWARESERIAL_H_ @@ -34,29 +34,29 @@ #include "Print.h" class HardwareSerial : public Print { - private: - uint8 usart_num; - uint32 max_baud; - GPIO_Port *gpio_port; - uint8 tx_pin; - uint8 rx_pin; - uint8 timer_num; - uint8 compare_num; - public: - HardwareSerial(uint8 usart_num, - uint32 max_baud, - GPIO_Port *gpio_port, - uint8 tx_pin, - uint8 rx_pin, - uint8 timer_num, - uint8 compare_num); - void begin(uint32); - void end(void); - uint32 available(void); - uint8 read(void); - void flush(void); - virtual void write(unsigned char); - using Print::write; + private: + uint8 usart_num; + uint32 max_baud; + GPIO_Port *gpio_port; + uint8 tx_pin; + uint8 rx_pin; + uint8 timer_num; + uint8 compare_num; + public: + HardwareSerial(uint8 usart_num, + uint32 max_baud, + GPIO_Port *gpio_port, + uint8 tx_pin, + uint8 rx_pin, + uint8 timer_num, + uint8 compare_num); + void begin(uint32); + void end(void); + uint32 available(void); + uint8 read(void); + void flush(void); + virtual void write(unsigned char); + using Print::write; }; extern HardwareSerial Serial1; extern HardwareSerial Serial2; diff --git a/wirish/ext_interrupts.c b/wirish/ext_interrupts.c index 6ba1d05..f02cdc5 100644 --- a/wirish/ext_interrupts.c +++ b/wirish/ext_interrupts.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. - * ****************************************************************************/ + *****************************************************************************/ /** * @file ext_interrupts.c @@ -36,22 +36,22 @@ * @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 */ + + /* 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 +65,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..fef8c8f 100644 --- a/wirish/ext_interrupts.h +++ b/wirish/ext_interrupts.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 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 } diff --git a/wirish/io.h b/wirish/io.h index e779604..647e79c 100644 --- a/wirish/io.h +++ b/wirish/io.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 io.h * - * @brief + * @brief Arduino-compatible digital pin I/O interface. */ #ifndef _IO_H @@ -38,7 +38,6 @@ extern "C"{ #endif - typedef enum WiringPinMode { OUTPUT, OUTPUT_OPEN_DRAIN, @@ -47,7 +46,8 @@ typedef enum WiringPinMode { INPUT_PULLUP, INPUT_PULLDOWN, INPUT_FLOATING, - PWM + PWM, + PWM_OPEN_DRAIN, } WiringPinMode; @@ -84,7 +84,7 @@ uint32 digitalRead(uint8); * to INPUT_ANALOG * analogRead(pin) * pin -> {A0-A16} - * */ + */ uint32 analogRead(uint8); #ifdef __cplusplus diff --git a/wirish/pwm.c b/wirish/pwm.c index 995e2c7..2f555ab 100644 --- a/wirish/pwm.c +++ b/wirish/pwm.c @@ -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 + * @brief Arduino-compatible PWM implementation. */ #include "wirish.h" @@ -40,8 +40,9 @@ void pwmWrite(uint8 pin, uint16 duty_cycle) { ccr = PIN_MAP[pin].timer_channel; - if (ccr == TIMER_INVALID) + if (ccr == TIMER_INVALID) { return; + } timer_pwm_write_ccr(ccr, duty_cycle); } diff --git a/wirish/pwm.h b/wirish/pwm.h index 927b685..fe170cd 100644 --- a/wirish/pwm.h +++ b/wirish/pwm.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 pwm.h * - * @brief + * @brief Arduino-compatible PWM interface. */ #ifndef _PWM_H diff --git a/wirish/time.c b/wirish/time.c index eaa3c9e..3a48197 100644 --- a/wirish/time.c +++ b/wirish/time.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,30 +20,30 @@ * 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 + * @brief Delay implementation. */ #include "libmaple.h" #include "systick.h" #include "time.h" -void delay(unsigned long ms) -{ - uint32 i; - for (i = 0; i < ms; i++) { - delayMicroseconds(1000); - } +void delay(unsigned long ms) { + uint32 i; + for (i = 0; i < ms; i++) { + delayMicroseconds(1000); + } } void delayMicroseconds(uint32 us) { - // So (2^32)/12 micros max, or less than 6 minutes + /* So (2^32)/12 micros max, or less than 6 minutes */ us *= 12; /* fudge for function call overhead */ us--; + int x = 4; asm volatile(" mov r0, %[us] \n\t" "1: subs r0, #1 \n\t" " bhi 1b \n\t" diff --git a/wirish/time.h b/wirish/time.h index f4612fa..742f28d 100644 --- a/wirish/time.h +++ b/wirish/time.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 + * @brief Timing and delay functions. */ #ifndef _TIME_H @@ -44,28 +44,28 @@ extern volatile uint32 systick_timer_millis; /* time in milliseconds since boot */ static inline uint32 millis(void) { - return systick_timer_millis; + return systick_timer_millis; } /* Time in microseconds since boot */ static inline uint32 micros(void) { - uint32 ms; - uint32 cycle_cnt; - uint32 res; + uint32 ms; + uint32 cycle_cnt; + uint32 res; - nvic_globalirq_disable(); + nvic_globalirq_disable(); - cycle_cnt = systick_get_count(); - ms = millis(); + cycle_cnt = systick_get_count(); + ms = millis(); - nvic_globalirq_enable(); + nvic_globalirq_enable(); - /* MAPLE_RELOAD_VAL is 1 less than the number of cycles it actually - takes to complete a systick reload */ - res = (ms * US_PER_MS) + - (MAPLE_RELOAD_VAL + 1 - cycle_cnt)/CYCLES_PER_MICROSECOND; + /* MAPLE_RELOAD_VAL is 1 less than the number of cycles it actually + takes to complete a systick reload */ + res = (ms * US_PER_MS) + + (MAPLE_RELOAD_VAL + 1 - cycle_cnt)/CYCLES_PER_MICROSECOND; - return res; + return res; } void delay(unsigned long ms); diff --git a/wirish/usb_serial.cpp b/wirish/usb_serial.cpp index fafdf49..405220a 100644 --- a/wirish/usb_serial.cpp +++ b/wirish/usb_serial.cpp @@ -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 wirish usb class for easy goin communication, uses libmaple's + * @brief Wirish USB class for easy communication, uses libmaple's * virtual com port implementation */ @@ -49,8 +49,10 @@ void USBSerial::write(uint8 ch) { if(!(usbIsConnected() && usbIsConfigured())) { return; } + uint16 status = 0; uint32 start = millis(); + while(status == 0 && (millis() - start <= USB_TIMEOUT)) { status = usbSendBytes(&ch, 1); } @@ -60,13 +62,15 @@ void USBSerial::write(const char *str) { if(!(usbIsConnected() && usbIsConfigured())) { return; } + uint32 len = strlen(str); uint16 status = 0; uint16 oldstatus = 0; uint32 start = millis(); + while(status < len && (millis() - start < USB_TIMEOUT)) { status += usbSendBytes((uint8*)str+status, len-status); - if(oldstatus != status) + if(oldstatus != status) start = millis(); oldstatus = status; } @@ -76,52 +80,55 @@ void USBSerial::write(void *buf, uint32 size) { if(!(usbIsConnected() && usbIsConfigured())) { return; } + if (!buf) { return; } + uint16 status = 0; uint16 oldstatus = 0; uint32 start = millis(); + while(status < size && (millis() - start < USB_TIMEOUT)) { status += usbSendBytes((uint8*)buf+status, size-status); - if(oldstatus != status) + if(oldstatus != status) start = millis(); oldstatus = status; } } uint32 USBSerial::available(void) { - return usbBytesAvailable(); + return usbBytesAvailable(); } uint32 USBSerial::read(void *buf, uint32 len) { - if (!buf) { - return 0; - } + if (!buf) { + return 0; + } - return usbReceiveBytes((uint8*)buf, len); + return usbReceiveBytes((uint8*)buf, len); } uint8 USBSerial::read(void) { - uint8 ch; - usbReceiveBytes(&ch, 1); - return ch; + uint8 ch; + usbReceiveBytes(&ch, 1); + return ch; } uint8 USBSerial::pending(void) { - return usbGetPending(); + return usbGetPending(); } uint8 USBSerial::getDTR(void) { - return usbGetDTR(); + return usbGetDTR(); } uint8 USBSerial::getRTS(void) { - return usbGetRTS(); + return usbGetRTS(); } uint8 USBSerial::isConnected(void) { - return (usbIsConnected() && usbIsConfigured()); + return (usbIsConnected() && usbIsConfigured()); } USBSerial SerialUSB; diff --git a/wirish/usb_serial.h b/wirish/usb_serial.h index 7c87c04..c228837 100644 --- a/wirish/usb_serial.h +++ b/wirish/usb_serial.h @@ -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 wirish usb class for easy goin communication, uses libmaple's - * virtual com port implementation + * @brief wirish usb class for easy goin communication, uses libmaple's + * virtual com port implementation */ #ifndef _USB_SERIAL_H_ @@ -33,25 +33,25 @@ #include "Print.h" class USBSerial : public Print { - public: - USBSerial(void); +public: + USBSerial(void); - void begin(void); - void end(void); + void begin(void); + void end(void); - uint32 available(void); + uint32 available(void); - uint32 read(void *buf, uint32 len); - uint8 read(void); + uint32 read(void *buf, uint32 len); + uint8 read(void); - void write(uint8); - void write(const char *str); - void write(void *, uint32); + void write(uint8); + void write(const char *str); + void write(void *, uint32); - uint8 getRTS(); - uint8 getDTR(); - uint8 isConnected(); - uint8 pending(); + uint8 getRTS(); + uint8 getDTR(); + uint8 isConnected(); + uint8 pending(); }; extern USBSerial SerialUSB; diff --git a/wirish/wirish.c b/wirish/wirish.c index 5407131..0abec41 100644 --- a/wirish/wirish.c +++ b/wirish/wirish.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,17 +20,16 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * ****************************************************************************/ + *****************************************************************************/ /** - * @brief generic maple board bring up: + * @brief generic maple board bring up: * - * By default, we bring up all maple boards running on the stm32 to 72mhz, - * clocked off the PLL, driven by the 8MHz external crystal. - * - * AHB and APB2 are clocked at 72MHz - * APB1 is clocked at 36MHz + * By default, we bring up all maple boards running on the stm32 to 72mhz, + * clocked off the PLL, driven by the 8MHz external crystal. * + * AHB and APB2 are clocked at 72MHz + * APB1 is clocked at 36MHz */ #include "wirish.h" @@ -44,35 +43,35 @@ #include "flash.h" void init(void) { - /* make sure the flash is ready before spinning the high speed clock up */ - flash_enable_prefetch(); - flash_set_latency(FLASH_WAIT_STATE_2); + /* make sure the flash is ready before spinning the high speed clock up */ + flash_enable_prefetch(); + flash_set_latency(FLASH_WAIT_STATE_2); - #if NR_FSMC > 0 - fsmc_native_sram_init(); - #endif +#if NR_FSMC > 0 + fsmc_native_sram_init(); +#endif - #if NR_DAC_PINS > 0 - dac_init(); - #endif +#if NR_DAC_PINS > 0 + dac_init(); +#endif - /* initialize clocks */ - rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9); - rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); - rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); - rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); + /* initialize clocks */ + rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9); + rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1); + rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2); + rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1); - nvic_init(); - systick_init(MAPLE_RELOAD_VAL); - gpio_init(); - adc_init(); - timer_init(TIMER1, 1); - timer_init(TIMER2, 1); - timer_init(TIMER3, 1); - timer_init(TIMER4, 1); - #if NR_TIMERS >= 8 - timer_init(TIMER5, 1); - timer_init(TIMER8, 1); - #endif - setupUSB(); + nvic_init(); + systick_init(MAPLE_RELOAD_VAL); + gpio_init(); + adc_init(); + timer_init(TIMER1, 1); + timer_init(TIMER2, 1); + timer_init(TIMER3, 1); + timer_init(TIMER4, 1); +#if NR_TIMERS >= 8 + timer_init(TIMER5, 1); + timer_init(TIMER8, 1); +#endif + setupUSB(); } diff --git a/wirish/wirish.h b/wirish/wirish.h index 7ede77c..c1c46cb 100644 --- a/wirish/wirish.h +++ b/wirish/wirish.h @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,14 +20,14 @@ * 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 Main include file for the Wirish core. * * Includes various Arduino wiring macros and bit defines */ - #ifndef _WIRISH_H_ #define _WIRISH_H_ @@ -62,14 +62,14 @@ extern "C"{ #define LSBFIRST 0 #define MSBFIRST 1 -#define lowByte(w) ((w) & 0xff) -#define highByte(w) ((w) >> 8) -#define bitRead(value, bit) (((value) >> (bit)) & 0x01) -#define bitSet(value, bit) ((value) |= (1UL << (bit))) -#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) -#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : \ - bitClear(value, bit)) -#define bit(b) (1UL << (b)) +#define lowByte(w) ((w) & 0xff) +#define highByte(w) ((w) >> 8) +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : \ + bitClear(value, bit)) +#define bit(b) (1UL << (b)) typedef uint8 boolean; typedef uint8 byte; diff --git a/wirish/wirish_analog.c b/wirish/wirish_analog.c index 1b911bc..3c63342 100644 --- a/wirish/wirish_analog.c +++ b/wirish/wirish_analog.c @@ -1,4 +1,4 @@ -/* ***************************************************************************** +/****************************************************************************** * The MIT License * * Copyright (c) 2010 Perry Hung. @@ -20,22 +20,22 @@ * 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 + * @brief Arduino-compatible ADC implementation. */ #include "libmaple.h" #include "wirish.h" #include "io.h" -/* Assumes that the ADC has been initialized and - * that the pin is set to ANALOG_INPUT */ +/* Assumes that the ADC has been initialized and that the pin is set + * to ANALOG_INPUT */ uint32 analogRead(uint8 pin) { if(PIN_MAP[pin].adc == ADC_INVALID) { return 0; - } + } return adc_read(PIN_MAP[pin].adc); } diff --git a/wirish/wirish_digital.c b/wirish/wirish_digital.c index c93c786..f4868da 100644 --- a/wirish/wirish_digital.c +++ b/wirish/wirish_digital.c @@ -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 + * @brief Arduino-compatible digital I/O implementation. */ #include "wirish.h" @@ -32,8 +32,9 @@ void pinMode(uint8 pin, WiringPinMode mode) { uint8 outputMode; - if (pin >= NR_GPIO_PINS) + if (pin >= NR_GPIO_PINS) { return; + } switch(mode) { case OUTPUT: @@ -58,6 +59,9 @@ void pinMode(uint8 pin, WiringPinMode mode) { case PWM: outputMode = GPIO_MODE_AF_OUTPUT_PP; break; + case PWM_OPEN_DRAIN: + outputMode = GPIO_MODE_AF_OUTPUT_OD; + break; default: ASSERT(0); return; @@ -68,14 +72,17 @@ void pinMode(uint8 pin, WiringPinMode mode) { uint32 digitalRead(uint8 pin) { - if (pin >= NR_GPIO_PINS) + if (pin >= NR_GPIO_PINS) { return 0; + } + return gpio_read_bit(PIN_MAP[pin].port, PIN_MAP[pin].pin); } void digitalWrite(uint8 pin, uint8 val) { - if (pin >= NR_GPIO_PINS) + if (pin >= NR_GPIO_PINS) { return; + } gpio_write_bit(PIN_MAP[pin].port, PIN_MAP[pin].pin, val); } diff --git a/wirish/wirish_math.cpp b/wirish/wirish_math.cpp index 0d907c4..12a21c3 100644 --- a/wirish/wirish_math.cpp +++ b/wirish/wirish_math.cpp @@ -1,54 +1,54 @@ /* - Modified by LeafLabs, LLC. - - Part of the Wiring project - http://wiring.org.co - Copyright (c) 2004-06 Hernando Barragan - Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/ - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - $Id$ -*/ + * Modified by LeafLabs, LLC. + * + * Part of the Wiring project - http://wiring.org.co Copyright (c) + * 2004-06 Hernando Barragan Modified 13 August 2006, David A. Mellis + * for Arduino - http://www.arduino.cc/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ #include <stdlib.h> #include "math.h" void randomSeed(unsigned int seed) { - if (seed != 0) { - srand(seed); - } + if (seed != 0) { + srand(seed); + } } long random(long howbig) { - if (howbig == 0) { - return 0; - } - return rand() % howbig; + if (howbig == 0) { + return 0; + } + + return rand() % howbig; } long random(long howsmall, long howbig) { - if (howsmall >= howbig) { - return howsmall; - } - long diff = howbig - howsmall; - return random(diff) + howsmall; + if (howsmall >= howbig) { + return howsmall; + } + + long diff = howbig - howsmall; + return random(diff) + howsmall; } long map(long x, long in_min, long in_max, long out_min, long out_max) { - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } diff --git a/wirish/wirish_math.h b/wirish/wirish_math.h index 8746d01..4543c1b 100644 --- a/wirish/wirish_math.h +++ b/wirish/wirish_math.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. - * ****************************************************************************/ + *****************************************************************************/ #ifndef _WIRING_MATH_H_ #define _WIRING_MATH_H_ @@ -34,11 +34,11 @@ long random(long); long random(long, long); long map(long, long, long, long, long); -#define PI 3.1415926535897932384626433832795 -#define HALF_PI 1.5707963267948966192313216916398 -#define TWO_PI 6.283185307179586476925286766559 -#define DEG_TO_RAD 0.017453292519943295769236907684886 -#define RAD_TO_DEG 57.295779513082320876798154814105 +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) @@ -52,7 +52,7 @@ long map(long, long, long, long, long); #ifdef abs #undef abs #endif -#define abs(x) (((x) > 0) ? (x) : -(unsigned)(x)) +#define abs(x) (((x) > 0) ? (x) : -(unsigned)(x)) #endif diff --git a/wirish/wirish_shift.c b/wirish/wirish_shift.c index 884b560..f67364d 100644 --- a/wirish/wirish_shift.c +++ b/wirish/wirish_shift.c @@ -1,38 +1,38 @@ /* - wiring_shift.c - shiftOut() function - Part of Arduino - http://www.arduino.cc/ - - Copyright (c) 2005-2006 David A. Mellis - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ -*/ + * wiring_shift.c - shiftOut() function + * Part of Arduino - http://www.arduino.cc/ + * + * Copyright (c) 2005-2006 David A. Mellis + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ + */ #include "wirish.h" -void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 val) -{ +void shiftOut(uint8 dataPin, uint8 clockPin, uint8 bitOrder, uint8 val) { int i; - for (i = 0; i < 8; i++) { - if (bitOrder == LSBFIRST) + for (i = 0; i < 8; i++) { + if (bitOrder == LSBFIRST) { digitalWrite(dataPin, !!(val & (1 << i))); - else + } else { digitalWrite(dataPin, !!(val & (1 << (7 - i)))); + } digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW); |