[NUCLEO_F401RE] Many corrections on pinmap, RTC, ...

pull/161/head
bcostm 2014-02-07 09:36:31 +01:00
parent 4ee89986b7
commit c08d507168
13 changed files with 122 additions and 63 deletions

View File

@ -37,10 +37,22 @@ extern "C" {
#endif
// See stm32f4xx_hal_gpio.h and stm32f4xx_hal_gpio_ex.h for values of MODE, PUPD and AFNUM
#define STM_PIN_DATA(MODE, PUPD, AFNUM) ((int)(((AFNUM) << 10) | ((PUPD) << 8) | ((MODE) << 0)))
#define STM_PIN_MODE(X) (((X) >> 0) & 0xFF)
#define STM_PIN_PUPD(X) (((X) >> 8) & 0x03)
#define STM_PIN_AFNUM(X) (((X) >> 10) & 0x0F)
#define STM_PIN_DATA(MODE, PUPD, AFNUM) ((int)(((AFNUM) << 7) | ((PUPD) << 4) | ((MODE) << 0)))
#define STM_PIN_MODE(X) (((X) >> 0) & 0x0F)
#define STM_PIN_PUPD(X) (((X) >> 4) & 0x07)
#define STM_PIN_AFNUM(X) (((X) >> 7) & 0x0F)
#define STM_MODE_INPUT (0)
#define STM_MODE_OUTPUT_PP (1)
#define STM_MODE_OUTPUT_OD (2)
#define STM_MODE_AF_PP (3)
#define STM_MODE_AF_OD (4)
#define STM_MODE_ANALOG (5)
#define STM_MODE_IT_RISING (6)
#define STM_MODE_IT_FALLING (7)
#define STM_MODE_IT_RISING_FALLING (8)
#define STM_MODE_EVT_RISING (9)
#define STM_MODE_EVT_FALLING (10)
#define STM_MODE_EVT_RISING_FALLING (11)
// High nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H)
// Low nibble = pin number

View File

@ -36,12 +36,12 @@
#include "stm32f4xx_hal.h"
static const PinMap PinMap_ADC[] = {
{PA_0, ADC_1, STM_PIN_DATA(GPIO_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN0
{PA_1, ADC_1, STM_PIN_DATA(GPIO_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN1
{PA_4, ADC_1, STM_PIN_DATA(GPIO_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN4
{PB_0, ADC_1, STM_PIN_DATA(GPIO_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN8
{PC_1, ADC_1, STM_PIN_DATA(GPIO_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN11
{PC_0, ADC_1, STM_PIN_DATA(GPIO_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN10
{PA_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN0
{PA_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN1
{PA_4, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN4
{PB_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN8
{PC_1, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN11
{PC_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN10
{NC, NC, 0}
};
@ -54,7 +54,7 @@ void analogin_init(analogin_t *obj, PinName pin) {
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
if (obj->adc == (ADCName)NC) {
error("ADC pin mapping failed");
error("ADC error: pinout mapping failed.");
}
// Configure GPIO

View File

@ -37,7 +37,7 @@ extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
uint32_t gpio_set(PinName pin) {
if (pin == NC) return 0;
pin_function(pin, STM_PIN_DATA(GPIO_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
return (uint32_t)(1 << ((uint32_t)pin & 0xF)); // Return the pin mask
}
@ -60,10 +60,10 @@ void gpio_init(gpio_t *obj, PinName pin, PinDirection direction) {
// Configure GPIO
if (direction == PIN_OUTPUT) {
pin_function(pin, STM_PIN_DATA(GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
pin_function(pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
}
else { // PIN_INPUT
pin_function(pin, STM_PIN_DATA(GPIO_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
}
@ -73,9 +73,9 @@ void gpio_mode(gpio_t *obj, PinMode mode) {
void gpio_dir(gpio_t *obj, PinDirection direction) {
if (direction == PIN_OUTPUT) {
pin_function(obj->pin, STM_PIN_DATA(GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
}
else { // PIN_INPUT
pin_function(obj->pin, STM_PIN_DATA(GPIO_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
}

View File

@ -54,9 +54,9 @@ static void handle_interrupt_in(uint32_t irq_index) {
uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]);
// Clear interrupt flag
if (__HAL_GPIO_EXTI_GET_IT(channel_pin[irq_index]) != RESET)
if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(channel_pin[irq_index]);
__HAL_GPIO_EXTI_CLEAR_FLAG(pin);
}
if (channel_ids[irq_index] == 0) return;
@ -111,7 +111,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
irq_index = 3;
break;
default:
error("This pin is not supported with InterruptIn.\n");
error("InterruptIn error: pin not supported.\n");
return -1;
}
@ -119,19 +119,17 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
uint32_t gpio_add = Set_GPIO_Clock(port_index);
// Configure GPIO
pin_function(pin, STM_PIN_DATA(GPIO_MODE_IT_FALLING, GPIO_NOPULL, 0));
pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0));
// Enable EXTI interrupt
NVIC_SetVector(irq_n, vector);
//NVIC_EnableIRQ(irq_n);
HAL_NVIC_SetPriority(irq_n, 2, 0);
HAL_NVIC_EnableIRQ(irq_n);
NVIC_EnableIRQ(irq_n);
// Save informations for future use
obj->irq_n = irq_n;
obj->irq_index = irq_index;
obj->event = EDGE_NONE;
obj->pin = pin;
channel_ids[irq_index] = id;
channel_gpio[irq_index] = gpio_add;
channel_pin[irq_index] = pin_index;
@ -142,19 +140,17 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
}
void gpio_irq_free(gpio_irq_t *obj) {
uint32_t pin_index = channel_pin[obj->irq_index];
channel_ids[obj->irq_index] = 0;
channel_gpio[obj->irq_index] = 0;
channel_pin[obj->irq_index] = 0;
// Disable EXTI line
pin_function((PinName)pin_index, STM_PIN_DATA(GPIO_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
obj->event = EDGE_NONE;
}
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
uint32_t mode = GPIO_MODE_INPUT;
uint32_t mode = STM_MODE_INPUT;
uint32_t pull = GPIO_NOPULL;
uint32_t pin_index = channel_pin[obj->irq_index];
if (enable) {
@ -162,33 +158,33 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
if (event == IRQ_RISE) {
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
mode = GPIO_MODE_IT_RISING_FALLING;
mode = STM_MODE_IT_RISING_FALLING;
obj->event = EDGE_BOTH;
}
else { // NONE or RISE
mode = GPIO_MODE_IT_RISING;
mode = STM_MODE_IT_RISING;
obj->event = EDGE_RISE;
}
}
if (event == IRQ_FALL) {
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
mode = GPIO_MODE_IT_RISING_FALLING;
mode = STM_MODE_IT_RISING_FALLING;
obj->event = EDGE_BOTH;
}
else { // NONE or FALL
mode = GPIO_MODE_IT_FALLING;
mode = STM_MODE_IT_FALLING;
obj->event = EDGE_FALL;
}
}
}
else {
mode = GPIO_MODE_INPUT;
mode = STM_MODE_INPUT;
pull = GPIO_NOPULL;
obj->event = EDGE_NONE;
}
pin_function((PinName)pin_index, STM_PIN_DATA(mode, pull, 0));
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
}
void gpio_irq_enable(gpio_irq_t *obj) {

View File

@ -62,7 +62,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
if (obj->i2c == (I2CName)NC) {
error("I2C pin mapping failed");
error("I2C error: pinout mapping failed.");
}
// Enable I2C clock
@ -99,7 +99,7 @@ void i2c_frequency(i2c_t *obj, int hz) {
HAL_I2C_Init(&I2cHandle);
}
else {
error("I2C error: max frequency is 400 kHz");
error("I2C error: frequency setting failed (max 400kHz).");
}
}

View File

@ -43,6 +43,7 @@ struct gpio_irq_s {
IRQn_Type irq_n;
uint32_t irq_index;
uint32_t event;
PinName pin;
};
struct port_s {

View File

@ -31,6 +31,22 @@
#include "error.h"
#include "stm32f4xx_hal.h"
// GPIO mode look-up table
static const uint32_t gpio_mode[12] = {
0x00000000, // 0 = GPIO_MODE_INPUT
0x00000001, // 1 = GPIO_MODE_OUTPUT_PP
0x00000011, // 2 = GPIO_MODE_OUTPUT_OD
0x00000002, // 3 = GPIO_MODE_AF_PP
0x00000012, // 4 = GPIO_MODE_AF_OD
0x00000003, // 5 = GPIO_MODE_ANALOG
0x10110000, // 6 = GPIO_MODE_IT_RISING
0x10210000, // 7 = GPIO_MODE_IT_FALLING
0x10310000, // 8 = GPIO_MODE_IT_RISING_FALLING
0x10120000, // 9 = GPIO_MODE_EVT_RISING
0x10220000, // 10 = GPIO_MODE_EVT_FALLING
0x10320000 // 11 = GPIO_MODE_EVT_RISING_FALLING
};
// Enable GPIO clock and return GPIO base address
uint32_t Set_GPIO_Clock(uint32_t port_idx) {
uint32_t gpio_add = 0;
@ -56,7 +72,7 @@ uint32_t Set_GPIO_Clock(uint32_t port_idx) {
__GPIOH_CLK_ENABLE();
break;
default:
error("GPIO port number is not correct.");
error("Pinmap error: wrong port number.");
break;
}
return gpio_add;
@ -83,7 +99,7 @@ void pin_function(PinName pin, int data) {
// Configure GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = (uint32_t)(1 << pin_index);
GPIO_InitStructure.Mode = mode;
GPIO_InitStructure.Mode = gpio_mode[mode];
GPIO_InitStructure.Pull = pupd;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Alternate = afnum;

View File

@ -66,10 +66,10 @@ void port_dir(port_t *obj, PinDirection dir) {
for (i = 0; i < 16; i++) { // Process all pins
if (obj->mask & (1 << i)) { // If the pin is used
if (dir == PIN_OUTPUT) {
pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
}
else { // PIN_INPUT
pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_MODE_INPUT, GPIO_NOPULL, 0));
pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
}
}
}

View File

@ -48,7 +48,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
if (obj->pwm == (PWMName)NC) {
error("PWM pinout mapping failed");
error("PWM error: pinout mapping failed.");
}
// Enable TIM clock

View File

@ -41,16 +41,36 @@ void rtc_init(void) {
RtcHandle.Instance = RTC;
// Enable Power clock
__PWR_CLK_ENABLE();
// Allow access to RTC
HAL_PWR_EnableBkUpAccess();
// Reset Backup domain
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
// Enable LSI clock
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
error("RTC error: Cannot initialize the LSI.");
error("RTC error: LSI clock initialization failed.");
}
// *** TODO** To be measured precisely using a timer input capture
uint32_t lsi_freq = 32700;
// Connect LSI to RTC
__HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
// Enable RTC clock
__HAL_RCC_RTC_ENABLE();
// This is LSI typical value
// To be measured precisely using a timer input capture [TODO]
uint32_t lsi_freq = 32000;
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
RtcHandle.Init.AsynchPrediv = 127;
@ -59,14 +79,27 @@ void rtc_init(void) {
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
error("RTC error: Cannot initialize the RTC peripheral.");
error("RTC error: RTC initialization failed.");
}
}
void rtc_free(void) {
RtcHandle.Instance = RTC;
// Enable Power clock
__PWR_CLK_ENABLE();
HAL_RTC_DeInit(&RtcHandle);
// Allow access to RTC
HAL_PWR_EnableBkUpAccess();
// Reset Backup domain
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
// Disable LSI clock
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
rtc_inited = 0;
}
@ -100,8 +133,9 @@ time_t rtc_read(void) {
RtcHandle.Instance = RTC;
// Read actual date and time
HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
// Warning: the time must be read first!
HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
// Setup a tm structure based on the RTC
timeinfo.tm_wday = dateStruct.WeekDay;

View File

@ -35,14 +35,14 @@
#include "stm32f4xx_hal.h"
static const PinMap PinMap_UART_TX[] = {
{PA_9, UART_1, STM_PIN_DATA(GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PA_2, UART_2, STM_PIN_DATA(GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PA_9, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PA_2, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{NC, NC, 0}
};
static const PinMap PinMap_UART_RX[] = {
{PA_10, UART_1, STM_PIN_DATA(GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PA_3, UART_2, STM_PIN_DATA(GPIO_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PA_10, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PA_3, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{NC, NC, 0}
};
@ -79,7 +79,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
if (obj->uart == (UARTName)NC) {
error("Serial pinout mapping failed");
error("Serial error: pinout mapping failed.");
}
// Enable USART clock

View File

@ -95,7 +95,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
if (obj->spi == (SPIName)NC) {
error("SPI pinout mapping failed");
error("SPI error: pinout mapping failed.");
}
// Enable SPI clock