mbed library with additional peripherals for ST F401 board
Fork of mbed-src by
This mbed LIB has additional peripherals for ST F401 board
- UART2 : PA_3 rx, PA_2 tx
- UART3 : PC_7 rx, PC_6 tx
- I2C2 : PB_3 SDA, PB_10 SCL
- I2C3 : PB_4 SDA, PA_8 SCL
Revision 77:b5886236e6f0, committed 2014-01-27
- Comitter:
- mbed_official
- Date:
- Mon Jan 27 15:30:04 2014 +0000
- Parent:
- 76:aeb1df146756
- Child:
- 78:2cab419ff388
- Commit message:
- Synchronized with git revision 84a8f2bcd4fff802c20a78cc2edf304135d243d2
Full URL: https://github.com/mbedmicro/mbed/commit/84a8f2bcd4fff802c20a78cc2edf304135d243d2/
Changed in this revision
--- a/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/cmsis_nvic.c Mon Jan 27 14:30:07 2014 +0000 +++ b/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F030R8/cmsis_nvic.c Mon Jan 27 15:30:04 2014 +0000 @@ -38,7 +38,7 @@ void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { int i; // Space for dynamic vectors, initialised to allocate in R/W - static volatile uint32_t* vectors = (uint32_t *)NVIC_RAM_VECTOR_ADDRESS; + static volatile uint32_t *vectors = (uint32_t *)NVIC_RAM_VECTOR_ADDRESS; // Copy and switch to dynamic vectors if first time called if (vtor_remap == 0) { @@ -46,6 +46,7 @@ for (i = 0; i < NVIC_NUM_VECTORS; i++) { vectors[i] = old_vectors[i]; } + SYSCFG->CFGR1 |= 0x03; // Embedded SRAM mapped at 0x00000000 vtor_remap = 1; // The vectors remap is done }
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c Mon Jan 27 14:30:07 2014 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/analogin_api.c Mon Jan 27 15:30:04 2014 +0000 @@ -122,7 +122,7 @@ } while(!ADC_GetFlagStatus(adc, ADC_FLAG_ADRDY)); // Wait ADC ready - + ADC_StartOfConversion(adc); // Start conversion while(ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/device.h Mon Jan 27 14:30:07 2014 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/device.h Mon Jan 27 15:30:04 2014 +0000 @@ -49,9 +49,9 @@ #define DEVICE_RTC 1 -#define DEVICE_PWMOUT 0 +#define DEVICE_PWMOUT 1 -#define DEVICE_SLEEP 0 +#define DEVICE_SLEEP 1 //=======================================
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/gpio_api.c Mon Jan 27 14:30:07 2014 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/gpio_api.c Mon Jan 27 15:30:04 2014 +0000 @@ -31,6 +31,8 @@ #include "pinmap.h" #include "error.h" +extern uint32_t Set_GPIO_Clock(uint32_t port_idx); + uint32_t gpio_set(PinName pin) { if (pin == NC) return 0; @@ -39,35 +41,17 @@ return (uint32_t)(1 << ((uint32_t)pin & 0xF)); // Return the pin mask } -void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) { +void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) { GPIO_TypeDef *gpio; - + if (pin == NC) return; uint32_t port_index = STM_PORT(pin); - - // Get GPIO structure base address - switch (port_index) { - case PortA: - gpio = (GPIO_TypeDef *)GPIOA_BASE; - break; - case PortB: - gpio = (GPIO_TypeDef *)GPIOB_BASE; - break; - case PortC: - gpio = (GPIO_TypeDef *)GPIOC_BASE; - break; - case PortD: - gpio = (GPIO_TypeDef *)GPIOD_BASE; - break; - case PortF: - gpio = (GPIO_TypeDef *)GPIOF_BASE; - break; - default: - error("GPIO port number is not correct."); - break; - } + // Enable GPIO clock + uint32_t gpio_add = Set_GPIO_Clock(port_index); + gpio = (GPIO_TypeDef *)gpio_add; + // Fill GPIO object structure for future use obj->pin = pin; obj->mask = gpio_set(pin);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/gpio_irq_api.c Mon Jan 27 15:30:04 2014 +0000 @@ -0,0 +1,210 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include <stddef.h> +#include "cmsis.h" + +#include "gpio_irq_api.h" +#include "pinmap.h" +#include "error.h" + +#define EDGE_NONE (0) +#define EDGE_RISE (1) +#define EDGE_FALL (2) +#define EDGE_BOTH (3) + +#define CHANNEL_NUM (3) + +static uint32_t channel_ids[CHANNEL_NUM] = {0, 0, 0}; +static uint32_t channel_gpio[CHANNEL_NUM] = {0, 0, 0}; +static uint32_t channel_pin[CHANNEL_NUM] = {0, 0, 0}; + +static gpio_irq_handler irq_handler; + +static void handle_interrupt_in(uint32_t irq_index) { + + // Retrieve the gpio and pin that generate the irq + GPIO_TypeDef *gpio = (GPIO_TypeDef *)(channel_gpio[irq_index]); + uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]); + + // Clear interrupt flag + if (EXTI_GetITStatus(pin) != RESET) + { + EXTI_ClearITPendingBit(pin); + } + + if (channel_ids[irq_index] == 0) return; + + // Check which edge has generated the irq + if ((gpio->IDR & pin) == 0) { + irq_handler(channel_ids[irq_index], IRQ_FALL); + } + else { + irq_handler(channel_ids[irq_index], IRQ_RISE); + } +} + +// The irq_index is passed to the function +static void gpio_irq0(void) {handle_interrupt_in(0);} +static void gpio_irq1(void) {handle_interrupt_in(1);} +static void gpio_irq2(void) {handle_interrupt_in(2);} + +extern uint32_t Set_GPIO_Clock(uint32_t port_idx); + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + uint32_t irq_index; + + if (pin == NC) return -1; + + uint32_t port_index = STM_PORT(pin); + uint32_t pin_index = STM_PIN(pin); + + // Select irq number and interrupt routine + switch (pin) { + case PC_13: // User button + irq_n = EXTI4_15_IRQn; + vector = (uint32_t)&gpio_irq0; + irq_index = 0; + break; + case PA_0: + irq_n = EXTI0_1_IRQn; + vector = (uint32_t)&gpio_irq1; + irq_index = 1; + break; + case PB_3: + irq_n = EXTI2_3_IRQn; + vector = (uint32_t)&gpio_irq2; + irq_index = 2; + break; + default: + error("This pin is not supported\n"); + return -1; + } + + // Enable GPIO clock + uint32_t gpio_add = Set_GPIO_Clock(port_index); + + // Enable SYSCFG clock + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); + + // Connect EXTI line to pin + SYSCFG_EXTILineConfig(port_index, pin_index); + + // Configure EXTI line + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + // Enable and set EXTI interrupt to the lowest priority + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = irq_n; + NVIC_InitStructure.NVIC_IRQChannelPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); + + // Save informations for future use + obj->irq_n = irq_n; + obj->irq_index = irq_index; + obj->event = EDGE_NONE; + channel_ids[irq_index] = id; + channel_gpio[irq_index] = gpio_add; + channel_pin[irq_index] = pin_index; + + irq_handler = handler; + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->irq_index] = 0; + channel_gpio[obj->irq_index] = 0; + channel_pin[obj->irq_index] = 0; + // Disable EXTI line + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_StructInit(&EXTI_InitStructure); + EXTI_Init(&EXTI_InitStructure); + obj->event = EDGE_NONE; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + EXTI_InitTypeDef EXTI_InitStructure; + + uint32_t pin_index = channel_pin[obj->irq_index]; + + EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + + if (event == IRQ_RISE) { + if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; + obj->event = EDGE_BOTH; + } + else { // NONE or RISE + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; + obj->event = EDGE_RISE; + } + } + + if (event == IRQ_FALL) { + if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; + obj->event = EDGE_BOTH; + } + else { // NONE or FALL + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; + obj->event = EDGE_FALL; + } + } + + if (enable) { + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + } + else { + EXTI_InitStructure.EXTI_LineCmd = DISABLE; + } + + EXTI_Init(&EXTI_InitStructure); +} + +void gpio_irq_enable(gpio_irq_t *obj) { + NVIC_EnableIRQ(obj->irq_n); +} + +void gpio_irq_disable(gpio_irq_t *obj) { + NVIC_DisableIRQ(obj->irq_n); + obj->event = EDGE_NONE; +}
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/objects.h Mon Jan 27 14:30:07 2014 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/objects.h Mon Jan 27 15:30:04 2014 +0000 @@ -40,9 +40,9 @@ #endif struct gpio_irq_s { - uint32_t ch; IRQn_Type irq_n; - uint32_t event; // 0=none, 1=rise, 2=fall, 3=rise+fall + uint32_t irq_index; + uint32_t event; }; struct port_s {
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pinmap.c Mon Jan 27 14:30:07 2014 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/pinmap.c Mon Jan 27 15:30:04 2014 +0000 @@ -30,6 +30,38 @@ #include "pinmap.h" #include "error.h" +// Not an API function +// Enable GPIO clock and return GPIO base address +uint32_t Set_GPIO_Clock(uint32_t port_idx) { + uint32_t gpio_add = 0; + switch (port_idx) { + case PortA: + gpio_add = GPIOA_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); + break; + case PortB: + gpio_add = GPIOB_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); + break; + case PortC: + gpio_add = GPIOC_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); + break; + case PortD: + gpio_add = GPIOD_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); + break; + case PortF: + gpio_add = GPIOF_BASE; + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); + break; + default: + error("Port number is not correct."); + break; + } + return gpio_add; +} + /** * Configure pin (mode, speed, output type and pull-up/pull-down) */ @@ -47,34 +79,11 @@ uint32_t port_index = STM_PORT(pin); uint32_t pin_index = STM_PIN(pin); - - // Get GPIO structure base address and enable clock - switch (port_index) { - case PortA: - gpio = (GPIO_TypeDef *)GPIOA_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); - break; - case PortB: - gpio = (GPIO_TypeDef *)GPIOB_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); - break; - case PortC: - gpio = (GPIO_TypeDef *)GPIOC_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); - break; - case PortD: - gpio = (GPIO_TypeDef *)GPIOD_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); - break; - case PortF: - gpio = (GPIO_TypeDef *)GPIOF_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); - break; - default: - error("GPIO port number is not correct."); - break; - } - + + // Enable GPIO clock + uint32_t gpio_add = Set_GPIO_Clock(port_index); + gpio = (GPIO_TypeDef *)gpio_add; + // Configure GPIO GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index); GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)mode; @@ -104,38 +113,15 @@ */ void pin_mode(PinName pin, PinMode mode) { GPIO_TypeDef *gpio; - + if (pin == NC) return; - + uint32_t port_index = STM_PORT(pin); uint32_t pin_index = STM_PIN(pin); - // Get GPIO structure base address and enable clock - switch (port_index) { - case PortA: - gpio = (GPIO_TypeDef *)GPIOA_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); - break; - case PortB: - gpio = (GPIO_TypeDef *)GPIOB_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); - break; - case PortC: - gpio = (GPIO_TypeDef *)GPIOC_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); - break; - case PortD: - gpio = (GPIO_TypeDef *)GPIOD_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); - break; - case PortF: - gpio = (GPIO_TypeDef *)GPIOF_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); - break; - default: - error("GPIO port number is not correct."); - break; - } + // Enable GPIO clock + uint32_t gpio_add = Set_GPIO_Clock(port_index); + gpio = (GPIO_TypeDef *)gpio_add; // Configure pull-up/pull-down resistors uint32_t pupd = (uint32_t)mode;
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c Mon Jan 27 14:30:07 2014 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/port_api.c Mon Jan 27 15:30:04 2014 +0000 @@ -34,6 +34,8 @@ #if DEVICE_PORTIN || DEVICE_PORTOUT +extern uint32_t Set_GPIO_Clock(uint32_t port_idx); + // high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) // low nibble = pin number PinName port_pin(PortName port, int pin_n) { @@ -42,35 +44,12 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { GPIO_TypeDef *gpio; - - uint32_t port_index = (uint32_t)port; + + uint32_t port_index = (uint32_t)port; // (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) - // Get GPIO structure base address and enable clock - switch (port_index) { - case PortA: - gpio = (GPIO_TypeDef *)GPIOA_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); - break; - case PortB: - gpio = (GPIO_TypeDef *)GPIOB_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); - break; - case PortC: - gpio = (GPIO_TypeDef *)GPIOC_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); - break; - case PortD: - gpio = (GPIO_TypeDef *)GPIOD_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); - break; - case PortF: - gpio = (GPIO_TypeDef *)GPIOF_BASE; - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE); - break; - default: - error("GPIO port number is not correct."); - break; - } + // Enable GPIO clock + uint32_t gpio_add = Set_GPIO_Clock(port_index); + gpio = (GPIO_TypeDef *)gpio_add; // Fill PORT object structure for future use obj->port = port;
--- a/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c Mon Jan 27 14:30:07 2014 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/serial_api.c Mon Jan 27 15:30:04 2014 +0000 @@ -96,7 +96,7 @@ pinmap_pinout(rx, PinMap_UART_RX); pin_mode(tx, PullUp); pin_mode(rx, PullUp); - + // Configure UART obj->baudrate = 9600; obj->databits = USART_WordLength_8b;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/hal/TARGET_STM/TARGET_NUCLEO_F030R8/sleep.c Mon Jan 27 15:30:04 2014 +0000 @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "sleep_api.h" +#include "cmsis.h" + +void sleep(void) +{ + SCB->SCR = 0; // Normal sleep mode for ARM core + __WFI(); +} + +void deepsleep(void) +{ + // Enable PWR clock + RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); + + // Request to enter STOP mode with regulator in low power mode + PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); +}