diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile b/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile new file mode 100644 index 00000000..d57ea7a8 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 3 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, see . +## + +BINARY = main +LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld + +include ../../Makefile.include + diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/README b/examples/stm32/l1/stm32l-discovery/button-irq-printf/README new file mode 100644 index 00000000..09e52bc2 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/README @@ -0,0 +1,4 @@ +* Counts how long the user button was held down (in ms) +* Uses one free running counter plus EXTI as an ugly input capture +115200@8n1 console on PA2 (tx only) + diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c new file mode 100644 index 00000000..1830c4dd --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c @@ -0,0 +1,117 @@ +/* + * Karl Palsson, 2012 +#include +#include +#include +#include +#include +#include +#include + +#include "syscfg.h" + +static struct state_t state; + +void clock_setup(void) { + /* Lots of things on all ports... */ + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); + + /* Enable clocks for USART2. */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); +} + +void gpio_setup(void) { + gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN); + + /* Setup GPIO pins for USART2 transmit. */ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); + + /* Setup USART2 TX pin as alternate function. */ + gpio_set_af(GPIOA, GPIO_AF7, GPIO2); +} + +void usart_setup(void) { + usart_set_baudrate(USART_CONSOLE, 115200); + usart_set_databits(USART_CONSOLE, 8); + usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1); + usart_set_mode(USART_CONSOLE, USART_MODE_TX); + usart_set_parity(USART_CONSOLE, USART_PARITY_NONE); + usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART_CONSOLE); +} + +/** + * Use USART_CONSOLE as a console. + * @param file + * @param ptr + * @param len + * @return + */ +int _write(int file, char *ptr, int len) { + int i; + + if (file == STDOUT_FILENO || file == STDERR_FILENO) { + for (i = 0; i < len; i++) { + if (ptr[i] == '\n') { + usart_send_blocking(USART_CONSOLE, '\r'); + } + usart_send_blocking(USART_CONSOLE, ptr[i]); + } + return i; + } + errno = EIO; + return -1; +} + +void BUTTON_DISCO_USER_isr(void) { + exti_reset_request(BUTTON_DISCO_USER_EXTI); + if (state.falling) { + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + // ILOG("fell: %d\n", TIM_CNT(TIM7)); + puts("fell!\n"); + } else { + puts("Rose!\n"); + // TIM_CNT(TIM7) = 0; + state.falling = true; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING); + } +} + +void setup_buttons(void) { + /* Enable EXTI0 interrupt. */ + nvic_enable_irq(BUTTON_DISCO_USER_NVIC); + + gpio_mode_setup(BUTTON_DISCO_USER_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, BUTTON_DISCO_USER_PIN); + + /* Configure the EXTI subsystem. */ + exti_select_source(BUTTON_DISCO_USER_EXTI, BUTTON_DISCO_USER_PORT); + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + exti_enable_request(BUTTON_DISCO_USER_EXTI); +} + +int main(void) { + int i; + int j = 0; + clock_setup(); + gpio_setup(); + usart_setup(); + puts("hi guys!\n"); + setup_buttons(); + while (1) { + puts("tick:"); + putchar('a' + (j++ % 26)); + gpio_toggle(GPIOB, GPIO7); /* LED on/off */ + for (i = 0; i < 100000; i++) /* Wait a bit. */ + __asm__("NOP"); + } + + return 0; +} diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h new file mode 100644 index 00000000..17eb3f10 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h @@ -0,0 +1,45 @@ +/* + * General configuration of the device + * + * Karl Palsson 2012 + */ + +#ifndef SYSCFG_H +#define SYSCFG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + + +#define USART_CONSOLE USART2 +#define USE_NASTYLOG 1 + +#define LED_DISCO_GREEN_PORT GPIOB +#define LED_DISCO_GREEN_PIN GPIO7 +#define LED_DISCO_BLUE_PORT GPIOB +#define LED_DISCO_BLUE_PIN GPIO6 + +#define BUTTON_DISCO_USER_PORT GPIOA +#define BUTTON_DISCO_USER_PIN GPIO0 +#define BUTTON_DISCO_USER_EXTI EXTI0 +#define BUTTON_DISCO_USER_isr exti0_isr +#define BUTTON_DISCO_USER_NVIC NVIC_EXTI0_IRQ + + + struct state_t { + bool falling; + }; + + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_H */ + diff --git a/include/libopencm3/stm32/f4/syscfg.h b/include/libopencm3/stm32/f4/syscfg.h deleted file mode 100644 index 7426f16c..00000000 --- a/include/libopencm3/stm32/f4/syscfg.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2011 Fergus Noble - * - * 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 3 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, see . - */ - -#ifndef LIBOPENCM3_SYSCFG_H -#define LIBOPENCM3_SYSCFG_H - -#include - -/* --- SYSCFG registers ------------------------------------------------------ */ - -#define SYSCFG_MEMRM MMIO32(SYSCFG_BASE + 0x00) - -#define SYSCFG_PMC MMIO32(SYSCFG_BASE + 0x04) - -/* External interrupt configuration register 1 (SYSCFG_EXTICR1) */ -#define SYSCFG_EXTICR1 MMIO32(SYSCFG_BASE + 0x08) - -/* External interrupt configuration register 2 (SYSCFG_EXTICR2) */ -#define SYSCFG_EXTICR2 MMIO32(SYSCFG_BASE + 0x0c) - -/* External interrupt configuration register 3 (SYSCFG_EXTICR3) */ -#define SYSCFG_EXTICR3 MMIO32(SYSCFG_BASE + 0x10) - -/* External interrupt configuration register 4 (SYSCFG_EXTICR4) */ -#define SYSCFG_EXTICR4 MMIO32(SYSCFG_BASE + 0x14) - -#define SYSCFG_CMPCR MMIO32(SYSCFG_BASE + 0x20) - -#endif - diff --git a/include/libopencm3/stm32/f2/syscfg.h b/include/libopencm3/stm32/syscfg.h similarity index 100% rename from include/libopencm3/stm32/f2/syscfg.h rename to include/libopencm3/stm32/syscfg.h diff --git a/lib/dispatch/vector_nvic.c b/lib/dispatch/vector_nvic.c index b8e9b7f5..33104eb2 100644 --- a/lib/dispatch/vector_nvic.c +++ b/lib/dispatch/vector_nvic.c @@ -4,6 +4,8 @@ # include "../stm32/f2/vector_nvic.c" #elif defined(STM32F4) # include "../stm32/f4/vector_nvic.c" +#elif defined(STM32L1) +# include "../stm32/l1/vector_nvic.c" #elif defined(EFM32TG) # include "../efm32/efm32tg/vector_nvic.c" diff --git a/lib/stm32/f4/exti.c b/lib/stm32/exti2.c similarity index 85% rename from lib/stm32/f4/exti.c rename to lib/stm32/exti2.c index f69e99ed..bea2f4d4 100644 --- a/lib/stm32/f4/exti.c +++ b/lib/stm32/exti2.c @@ -2,6 +2,7 @@ * This file is part of the libopencm3 project. * * Copyright (C) 2010 Mark Butler + * Copyright (C) 2012 Karl Palsson * * 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 @@ -15,11 +16,22 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . + * + * This provides the code for the "next gen" EXTI block provided in F2/F4/L1 + * devices. (differences only in the source selection) */ #include -#include +#include +#if defined(STM32F2) +#include +#elif defined(STM32F4) #include +#elif defined(STM32L1) +#include +#else +#error "invalid/unknown stm32 family for this code" +#endif void exti_set_trigger(u32 extis, exti_trigger_type trig) { @@ -121,18 +133,24 @@ void exti_select_source(u32 exti, u32 gpioport) case GPIOE: bits = 0xb; break; +#if defined(STM32L1) +#else case GPIOF: bits = 0xa; break; case GPIOG: bits = 0x9; break; +#endif case GPIOH: bits = 0x8; break; +#if defined(STM32L1) +#else case GPIOI: bits = 0x7; break; +#endif } /* Ensure that only valid EXTI lines are used. */ diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile index 5cbb9770..e3d73feb 100644 --- a/lib/stm32/f2/Makefile +++ b/lib/stm32/f2/Makefile @@ -29,7 +29,7 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ # ARFLAGS = rcsv ARFLAGS = rcs OBJS = rcc.o gpio.o usart.o spi.o flash.o \ - i2c.o exti.o timer.o + i2c.o exti2.o timer.o VPATH += ../../usb:../:../../cm3 diff --git a/lib/stm32/f2/exti.c b/lib/stm32/f2/exti.c deleted file mode 100644 index 5280914e..00000000 --- a/lib/stm32/f2/exti.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Mark Butler - * - * 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 3 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, see . - */ - -#include -#include -#include - -void exti_set_trigger(u32 extis, exti_trigger_type trig) -{ - switch (trig) { - case EXTI_TRIGGER_RISING: - EXTI_RTSR |= extis; - EXTI_FTSR &= ~extis; - break; - case EXTI_TRIGGER_FALLING: - EXTI_RTSR &= ~extis; - EXTI_FTSR |= extis; - break; - case EXTI_TRIGGER_BOTH: - EXTI_RTSR |= extis; - EXTI_FTSR |= extis; - break; - } -} - -void exti_enable_request(u32 extis) -{ - /* Enable interrupts. */ - EXTI_IMR |= extis; - - /* Enable events. */ - EXTI_EMR |= extis; -} - -void exti_disable_request(u32 extis) -{ - /* Disable interrupts. */ - EXTI_IMR &= ~extis; - - /* Disable events. */ - EXTI_EMR &= ~extis; -} - -/* - * Reset the interrupt request by writing a 1 to the corresponding - * pending bit register. - */ -void exti_reset_request(u32 extis) -{ - EXTI_PR = extis; -} - -/* - * Remap an external interrupt line to the corresponding pin on the - * specified GPIO port. - * - * TODO: This could be rewritten in fewer lines of code. - */ -void exti_select_source(u32 exti, u32 gpioport) -{ - u8 shift, bits; - - shift = bits = 0; - - switch (exti) { - case EXTI0: - case EXTI4: - case EXTI8: - case EXTI12: - shift = 0; - break; - case EXTI1: - case EXTI5: - case EXTI9: - case EXTI13: - shift = 4; - break; - case EXTI2: - case EXTI6: - case EXTI10: - case EXTI14: - shift = 8; - break; - case EXTI3: - case EXTI7: - case EXTI11: - case EXTI15: - shift = 12; - break; - } - - switch (gpioport) { - case GPIOA: - bits = 0xf; - break; - case GPIOB: - bits = 0xe; - break; - case GPIOC: - bits = 0xd; - break; - case GPIOD: - bits = 0xc; - break; - case GPIOE: - bits = 0xb; - break; - case GPIOF: - bits = 0xa; - break; - case GPIOG: - bits = 0x9; - break; - } - - /* Ensure that only valid EXTI lines are used. */ - if (exti < EXTI4) { - SYSCFG_EXTICR1 &= ~(0x000F << shift); - SYSCFG_EXTICR1 |= (~bits << shift); - } else if (exti < EXTI8) { - SYSCFG_EXTICR2 &= ~(0x000F << shift); - SYSCFG_EXTICR2 |= (~bits << shift); - } else if (exti < EXTI12) { - SYSCFG_EXTICR3 &= ~(0x000F << shift); - SYSCFG_EXTICR3 |= (~bits << shift); - } else if (exti < EXTI16) { - SYSCFG_EXTICR4 &= ~(0x000F << shift); - SYSCFG_EXTICR4 |= (~bits << shift); - } -} diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 19ea8efd..1e3192b2 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -30,7 +30,7 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ # ARFLAGS = rcsv ARFLAGS = rcs OBJS = rcc.o gpio.o usart.o spi.o flash.o \ - i2c.o exti.o pwr.o timer.o \ + i2c.o exti2.o pwr.o timer.o \ usb.o usb_standard.o usb_control.o usb_fx07_common.o usb_f107.o \ usb_f207.o adc.o diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile index f852239f..71a6505d 100644 --- a/lib/stm32/l1/Makefile +++ b/lib/stm32/l1/Makefile @@ -25,10 +25,10 @@ CC = $(PREFIX)-gcc AR = $(PREFIX)-ar CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ - -ffunction-sections -fdata-sections -MD -DSTM32F1 + -ffunction-sections -fdata-sections -MD -DSTM32L1 # ARFLAGS = rcsv ARFLAGS = rcs -OBJS = rcc.o gpio.o desig.o crc.o usart.o +OBJS = rcc.o gpio.o desig.o crc.o usart.o exti2.o VPATH += ../../usb:../:../../cm3