Merge pull request #277 from bcostm/master

[NUCLEO_F401RE] Add LSE configuration for RTC, remove trailing spaces, t...
pull/279/head
Bogdan Marinescu 2014-04-28 15:55:37 +01:00
commit d57a23dd6e
22 changed files with 458 additions and 395 deletions

View File

@ -27,7 +27,8 @@
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LR_IROM1 0x08000000 0x80000 { ; load region size_region (512K) ; STM32F401RE: 512KB FLASH + 96KB SRAM
LR_IROM1 0x08000000 0x80000 { ; load region size_region
ER_IROM1 0x08000000 0x80000 { ; load address = execution address ER_IROM1 0x08000000 0x80000 { ; load address = execution address
*.o (RESET, +First) *.o (RESET, +First)

View File

@ -27,7 +27,8 @@
; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LR_IROM1 0x08000000 0x80000 { ; load region size_region (512K) ; STM32F401RE: 512KB FLASH + 96KB SRAM
LR_IROM1 0x08000000 0x80000 { ; load region size_region
ER_IROM1 0x08000000 0x80000 { ; load address = execution address ER_IROM1 0x08000000 0x80000 { ; load address = execution address
*.o (RESET, +First) *.o (RESET, +First)

View File

@ -196,6 +196,10 @@ typedef enum
* @} * @}
*/ */
#if defined (USE_HAL_DRIVER)
#include "stm32f4xx_hal.h"
#endif /* USE_HAL_DRIVER */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -103,7 +103,7 @@
#endif /* HSE_VALUE */ #endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT) #if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */ #define HSE_STARTUP_TIMEOUT ((uint32_t)50) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */ #endif /* HSE_STARTUP_TIMEOUT */
/** /**
@ -115,6 +115,14 @@
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */ #endif /* HSI_VALUE */
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
/** /**
* @brief External clock source for I2S peripheral * @brief External clock source for I2S peripheral
* This value is used by the I2S HAL module to compute the I2S clock source * This value is used by the I2S HAL module to compute the I2S clock source
@ -131,7 +139,8 @@
/** /**
* @brief This is the HAL system configuration section * @brief This is the HAL system configuration section
*/ */
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ #define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)3) /*!< tick interrupt priority */
#define USE_RTOS 0 #define USE_RTOS 0
#define PREFETCH_ENABLE 1 #define PREFETCH_ENABLE 1
#define INSTRUCTION_CACHE_ENABLE 1 #define INSTRUCTION_CACHE_ENABLE 1

View File

@ -190,7 +190,7 @@ typedef struct
#define DBP_TIMEOUT_VALUE ((uint32_t)100) #define DBP_TIMEOUT_VALUE ((uint32_t)100)
#define LSE_TIMEOUT_VALUE ((uint32_t)5000) #define LSE_TIMEOUT_VALUE ((uint32_t)100)
/** /**
* @} * @}
*/ */

View File

@ -32,8 +32,8 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * 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. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
****************************************************************************** ******************************************************************************
*/ */
/** @addtogroup CMSIS /** @addtogroup CMSIS
* @{ * @{

View File

@ -41,7 +41,7 @@ typedef enum {
} ADCName; } ADCName;
typedef enum { typedef enum {
UART_1 = (int)USART1_BASE, UART_1 = (int)USART1_BASE,
UART_2 = (int)USART2_BASE, UART_2 = (int)USART2_BASE,
UART_6 = (int)USART6_BASE UART_6 = (int)USART6_BASE
} UARTName; } UARTName;

View File

@ -26,14 +26,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "analogin_api.h" #include "analogin_api.h"
#include "wait_api.h"
#if DEVICE_ANALOGIN #if DEVICE_ANALOGIN
#include "wait_api.h"
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include "stm32f4xx_hal.h"
static const PinMap PinMap_ADC[] = { static const PinMap PinMap_ADC[] = {
{PA_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN0 {PA_0, ADC_1, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)}, // ADC1_IN0
@ -59,8 +58,8 @@ ADC_HandleTypeDef AdcHandle;
int adc_inited = 0; int adc_inited = 0;
void analogin_init(analogin_t *obj, PinName pin) { void analogin_init(analogin_t *obj, PinName pin) {
// Get the peripheral name (ADC_1, ADC_2...) from the pin and assign it to the object // Get the peripheral name from the pin and assign it to the object
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC); obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
if (obj->adc == (ADCName)NC) { if (obj->adc == (ADCName)NC) {
@ -76,7 +75,7 @@ void analogin_init(analogin_t *obj, PinName pin) {
// The ADC initialization is done once // The ADC initialization is done once
if (adc_inited == 0) { if (adc_inited == 0) {
adc_inited = 1; adc_inited = 1;
// Enable ADC clock // Enable ADC clock
__ADC1_CLK_ENABLE(); __ADC1_CLK_ENABLE();
@ -93,97 +92,93 @@ void analogin_init(analogin_t *obj, PinName pin) {
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 1; AdcHandle.Init.NbrOfConversion = 1;
AdcHandle.Init.DMAContinuousRequests = DISABLE; AdcHandle.Init.DMAContinuousRequests = DISABLE;
AdcHandle.Init.EOCSelection = DISABLE; AdcHandle.Init.EOCSelection = DISABLE;
HAL_ADC_Init(&AdcHandle); HAL_ADC_Init(&AdcHandle);
} }
} }
static inline uint16_t adc_read(analogin_t *obj) { static inline uint16_t adc_read(analogin_t *obj) {
ADC_ChannelConfTypeDef sConfig; ADC_ChannelConfTypeDef sConfig;
AdcHandle.Instance = (ADC_TypeDef *)(obj->adc);
// Configure ADC channel AdcHandle.Instance = (ADC_TypeDef *)(obj->adc);
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Offset = 0;
switch (obj->pin) { // Configure ADC channel
case PA_0: sConfig.Rank = 1;
sConfig.Channel = ADC_CHANNEL_0; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
break; sConfig.Offset = 0;
case PA_1:
sConfig.Channel = ADC_CHANNEL_1; switch (obj->pin) {
break; case PA_0:
case PA_2: sConfig.Channel = ADC_CHANNEL_0;
sConfig.Channel = ADC_CHANNEL_2; break;
break; case PA_1:
case PA_3: sConfig.Channel = ADC_CHANNEL_1;
sConfig.Channel = ADC_CHANNEL_3; break;
break; case PA_2:
case PA_4: sConfig.Channel = ADC_CHANNEL_2;
sConfig.Channel = ADC_CHANNEL_4; break;
break; case PA_3:
case PA_5: sConfig.Channel = ADC_CHANNEL_3;
sConfig.Channel = ADC_CHANNEL_5; break;
break; case PA_4:
case PA_6: sConfig.Channel = ADC_CHANNEL_4;
sConfig.Channel = ADC_CHANNEL_6; break;
break; case PA_5:
case PA_7: sConfig.Channel = ADC_CHANNEL_5;
sConfig.Channel = ADC_CHANNEL_7; break;
break; case PA_6:
case PB_0: sConfig.Channel = ADC_CHANNEL_6;
sConfig.Channel = ADC_CHANNEL_8; break;
break; case PA_7:
case PB_1: sConfig.Channel = ADC_CHANNEL_7;
sConfig.Channel = ADC_CHANNEL_9; break;
break; case PB_0:
case PC_0: sConfig.Channel = ADC_CHANNEL_8;
sConfig.Channel = ADC_CHANNEL_10; break;
break; case PB_1:
case PC_1: sConfig.Channel = ADC_CHANNEL_9;
sConfig.Channel = ADC_CHANNEL_11; break;
break; case PC_0:
case PC_2: sConfig.Channel = ADC_CHANNEL_10;
sConfig.Channel = ADC_CHANNEL_12; break;
break; case PC_1:
case PC_3: sConfig.Channel = ADC_CHANNEL_11;
sConfig.Channel = ADC_CHANNEL_13; break;
break; case PC_2:
case PC_4: sConfig.Channel = ADC_CHANNEL_12;
sConfig.Channel = ADC_CHANNEL_14; break;
break; case PC_3:
case PC_5: sConfig.Channel = ADC_CHANNEL_13;
sConfig.Channel = ADC_CHANNEL_15; break;
break; case PC_4:
default: sConfig.Channel = ADC_CHANNEL_14;
return 0; break;
} case PC_5:
sConfig.Channel = ADC_CHANNEL_15;
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig); break;
default:
HAL_ADC_Start(&AdcHandle); // Start conversion return 0;
}
HAL_ADC_PollForConversion(&AdcHandle, 10); // Wait end of conversion
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
if (HAL_ADC_GetState(&AdcHandle) == HAL_ADC_STATE_EOC_REG)
{ HAL_ADC_Start(&AdcHandle); // Start conversion
return(HAL_ADC_GetValue(&AdcHandle)); // Get conversion value
} // Wait end of conversion and get value
else if (HAL_ADC_PollForConversion(&AdcHandle, 10) == HAL_OK) {
{ return (HAL_ADC_GetValue(&AdcHandle));
return 0; } else {
} return 0;
}
} }
uint16_t analogin_read_u16(analogin_t *obj) { uint16_t analogin_read_u16(analogin_t *obj) {
return(adc_read(obj)); return (adc_read(obj));
} }
float analogin_read(analogin_t *obj) { float analogin_read(analogin_t *obj) {
uint16_t value = adc_read(obj); uint16_t value = adc_read(obj);
return (float)value * (1.0f / (float)0xFFF); // 12 bits range return (float)value * (1.0f / (float)0xFFF); // 12 bits range
} }
#endif #endif

View File

@ -30,11 +30,10 @@
#include "gpio_api.h" #include "gpio_api.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include "stm32f4xx_hal.h"
extern uint32_t Set_GPIO_Clock(uint32_t port_idx); extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
uint32_t gpio_set(PinName pin) { uint32_t gpio_set(PinName pin) {
if (pin == NC) return 0; if (pin == NC) return 0;
pin_function(pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); pin_function(pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
@ -46,11 +45,11 @@ void gpio_init(gpio_t *obj, PinName pin) {
if (pin == NC) return; if (pin == NC) return;
uint32_t port_index = STM_PORT(pin); uint32_t port_index = STM_PORT(pin);
// Enable GPIO clock // Enable GPIO clock
uint32_t gpio_add = Set_GPIO_Clock(port_index); uint32_t gpio_add = Set_GPIO_Clock(port_index);
GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add; GPIO_TypeDef *gpio = (GPIO_TypeDef *)gpio_add;
// Fill GPIO object structure for future use // Fill GPIO object structure for future use
obj->pin = pin; obj->pin = pin;
obj->mask = gpio_set(pin); obj->mask = gpio_set(pin);
@ -66,8 +65,7 @@ void gpio_mode(gpio_t *obj, PinMode mode) {
void gpio_dir(gpio_t *obj, PinDirection direction) { void gpio_dir(gpio_t *obj, PinDirection direction) {
if (direction == PIN_OUTPUT) { if (direction == PIN_OUTPUT) {
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0)); pin_function(obj->pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
} } else { // PIN_INPUT
else { // PIN_INPUT
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
} }
} }

View File

@ -29,10 +29,8 @@
*/ */
#include <stddef.h> #include <stddef.h>
#include "cmsis.h" #include "cmsis.h"
#include "gpio_irq_api.h" #include "gpio_irq_api.h"
#include "pinmap.h" #include "pinmap.h"
#include "stm32f4xx_hal.h"
#include "error.h" #include "error.h"
#define EDGE_NONE (0) #define EDGE_NONE (0)
@ -54,30 +52,49 @@ static void handle_interrupt_in(uint32_t irq_index) {
uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]); uint32_t pin = (uint32_t)(1 << channel_pin[irq_index]);
// Clear interrupt flag // Clear interrupt flag
if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) {
{
__HAL_GPIO_EXTI_CLEAR_FLAG(pin); __HAL_GPIO_EXTI_CLEAR_FLAG(pin);
} }
if (channel_ids[irq_index] == 0) return; if (channel_ids[irq_index] == 0) return;
// Check which edge has generated the irq // Check which edge has generated the irq
if ((gpio->IDR & pin) == 0) { if ((gpio->IDR & pin) == 0) {
irq_handler(channel_ids[irq_index], IRQ_FALL); irq_handler(channel_ids[irq_index], IRQ_FALL);
} } else {
else {
irq_handler(channel_ids[irq_index], IRQ_RISE); irq_handler(channel_ids[irq_index], IRQ_RISE);
} }
} }
// The irq_index is passed to the function // The irq_index is passed to the function
static void gpio_irq0(void) {handle_interrupt_in(0);} // EXTI line 0 // EXTI line 0
static void gpio_irq1(void) {handle_interrupt_in(1);} // EXTI line 1 static void gpio_irq0(void) {
static void gpio_irq2(void) {handle_interrupt_in(2);} // EXTI line 2 handle_interrupt_in(0);
static void gpio_irq3(void) {handle_interrupt_in(3);} // EXTI line 3 }
static void gpio_irq4(void) {handle_interrupt_in(4);} // EXTI line 4 // EXTI line 1
static void gpio_irq5(void) {handle_interrupt_in(5);} // EXTI lines 5 to 9 static void gpio_irq1(void) {
static void gpio_irq6(void) {handle_interrupt_in(6);} // EXTI lines 10 to 15 handle_interrupt_in(1);
}
// EXTI line 2
static void gpio_irq2(void) {
handle_interrupt_in(2);
}
// EXTI line 3
static void gpio_irq3(void) {
handle_interrupt_in(3);
}
// EXTI line 4
static void gpio_irq4(void) {
handle_interrupt_in(4);
}
// EXTI lines 5 to 9
static void gpio_irq5(void) {
handle_interrupt_in(5);
}
// EXTI lines 10 to 15
static void gpio_irq6(void) {
handle_interrupt_in(6);
}
extern uint32_t Set_GPIO_Clock(uint32_t port_idx); extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
@ -138,7 +155,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
irq_index = 6; irq_index = 6;
break; break;
default: default:
error("InterruptIn error: pin not supported."); error("InterruptIn error: pin not supported.\n");
return -1; return -1;
} }
@ -147,7 +164,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
// Configure GPIO // Configure GPIO
pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0));
// Enable EXTI interrupt // Enable EXTI interrupt
NVIC_SetVector(irq_n, vector); NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n); NVIC_EnableIRQ(irq_n);
@ -160,9 +177,9 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
channel_ids[irq_index] = id; channel_ids[irq_index] = id;
channel_gpio[irq_index] = gpio_add; channel_gpio[irq_index] = gpio_add;
channel_pin[irq_index] = pin_index; channel_pin[irq_index] = pin_index;
irq_handler = handler; irq_handler = handler;
return 0; return 0;
} }
@ -180,37 +197,34 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
uint32_t pull = GPIO_NOPULL; uint32_t pull = GPIO_NOPULL;
if (enable) { if (enable) {
pull = GPIO_NOPULL; pull = GPIO_NOPULL;
if (event == IRQ_RISE) { if (event == IRQ_RISE) {
if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_RISING_FALLING; mode = STM_MODE_IT_RISING_FALLING;
obj->event = EDGE_BOTH; obj->event = EDGE_BOTH;
} } else { // NONE or RISE
else { // NONE or RISE
mode = STM_MODE_IT_RISING; mode = STM_MODE_IT_RISING;
obj->event = EDGE_RISE; obj->event = EDGE_RISE;
} }
} }
if (event == IRQ_FALL) { if (event == IRQ_FALL) {
if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) {
mode = STM_MODE_IT_RISING_FALLING; mode = STM_MODE_IT_RISING_FALLING;
obj->event = EDGE_BOTH; obj->event = EDGE_BOTH;
} } else { // NONE or FALL
else { // NONE or FALL
mode = STM_MODE_IT_FALLING; mode = STM_MODE_IT_FALLING;
obj->event = EDGE_FALL; obj->event = EDGE_FALL;
} }
} }
} } else {
else {
mode = STM_MODE_INPUT; mode = STM_MODE_INPUT;
pull = GPIO_NOPULL; pull = GPIO_NOPULL;
obj->event = EDGE_NONE; obj->event = EDGE_NONE;
} }
pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0)); pin_function(obj->pin, STM_PIN_DATA(mode, pull, 0));
} }

View File

@ -50,8 +50,7 @@ typedef struct {
static inline void gpio_write(gpio_t *obj, int value) { static inline void gpio_write(gpio_t *obj, int value) {
if (value) { if (value) {
*obj->reg_set = obj->mask; *obj->reg_set = obj->mask;
} } else {
else {
*obj->reg_clr = obj->mask; *obj->reg_clr = obj->mask;
} }
} }

View File

@ -34,11 +34,10 @@
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include "stm32f4xx_hal.h"
/* Timeout values for flags and events waiting loops. These timeouts are /* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted. */ not remain stuck if the I2C communication is corrupted. */
#define FLAG_TIMEOUT ((int)0x1000) #define FLAG_TIMEOUT ((int)0x1000)
#define LONG_TIMEOUT ((int)0x8000) #define LONG_TIMEOUT ((int)0x8000)
@ -61,19 +60,19 @@ static const PinMap PinMap_I2C_SCL[] = {
I2C_HandleTypeDef I2cHandle; I2C_HandleTypeDef I2cHandle;
void i2c_init(i2c_t *obj, PinName sda, PinName scl) { void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
// Determine the I2C to use // Determine the I2C to use
I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl); obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
if (obj->i2c == (I2CName)NC) { if (obj->i2c == (I2CName)NC) {
error("I2C error: pinout mapping failed."); error("I2C error: pinout mapping failed.");
} }
// Enable I2C clock // Enable I2C clock
if (obj->i2c == I2C_1) { if (obj->i2c == I2C_1) {
__I2C1_CLK_ENABLE(); __I2C1_CLK_ENABLE();
} }
if (obj->i2c == I2C_2) { if (obj->i2c == I2C_2) {
@ -88,17 +87,17 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
pinmap_pinout(scl, PinMap_I2C_SCL); pinmap_pinout(scl, PinMap_I2C_SCL);
pin_mode(sda, OpenDrain); pin_mode(sda, OpenDrain);
pin_mode(scl, OpenDrain); pin_mode(scl, OpenDrain);
// Reset to clear pending flags if any // Reset to clear pending flags if any
i2c_reset(obj); i2c_reset(obj);
// I2C configuration // I2C configuration
i2c_frequency(obj, 100000); // 100 kHz per default i2c_frequency(obj, 100000); // 100 kHz per default
} }
void i2c_frequency(i2c_t *obj, int hz) { void i2c_frequency(i2c_t *obj, int hz) {
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
if ((hz != 0) && (hz <= 400000)) { if ((hz != 0) && (hz <= 400000)) {
// I2C configuration // I2C configuration
I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
@ -119,38 +118,38 @@ void i2c_frequency(i2c_t *obj, int hz) {
inline int i2c_start(i2c_t *obj) { inline int i2c_start(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout; int timeout;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Clear Acknowledge failure flag // Clear Acknowledge failure flag
__HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF); __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
// Generate the START condition // Generate the START condition
i2c->CR1 |= I2C_CR1_START; i2c->CR1 |= I2C_CR1_START;
// Wait the START condition has been correctly sent // Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) { while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
if ((timeout--) == 0) { if ((timeout--) == 0) {
return 1; return 1;
} }
} }
return 0; return 0;
} }
inline int i2c_stop(i2c_t *obj) { inline int i2c_stop(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
// Generate the STOP condition // Generate the STOP condition
i2c->CR1 |= I2C_CR1_STOP; i2c->CR1 |= I2C_CR1_STOP;
return 0; return 0;
} }
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
if (length == 0) return 0; if (length == 0) return 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Reception process with 5 seconds timeout // Reception process with 5 seconds timeout
@ -163,21 +162,21 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
if (length == 0) return 0; if (length == 0) return 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Transmission process with 5 seconds timeout // Transmission process with 5 seconds timeout
if (HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)address, (uint8_t *)data, length, 5000) != HAL_OK) { if (HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)address, (uint8_t *)data, length, 5000) != HAL_OK) {
return 0; // Error return 0; // Error
} }
return length; return length;
} }
int i2c_byte_read(i2c_t *obj, int last) { int i2c_byte_read(i2c_t *obj, int last) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout; int timeout;
if (last) { if (last) {
// Don't acknowledge the last byte // Don't acknowledge the last byte
i2c->CR1 &= ~I2C_CR1_ACK; i2c->CR1 &= ~I2C_CR1_ACK;
@ -189,11 +188,11 @@ int i2c_byte_read(i2c_t *obj, int last) {
// Wait until the byte is received // Wait until the byte is received
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) { while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
if ((timeout--) == 0) { if ((timeout--) == 0) {
return 0; return 0;
} }
} }
return (int)i2c->DR; return (int)i2c->DR;
} }
@ -204,19 +203,19 @@ int i2c_byte_write(i2c_t *obj, int data) {
i2c->DR = (uint8_t)data; i2c->DR = (uint8_t)data;
// Wait until the byte is transmitted // Wait until the byte is transmitted
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) && while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) &&
(__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == RESET)) { (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == RESET)) {
if ((timeout--) == 0) { if ((timeout--) == 0) {
return 0; return 0;
} }
} }
return 1; return 1;
} }
void i2c_reset(i2c_t *obj) { void i2c_reset(i2c_t *obj) {
if (obj->i2c == I2C_1) { if (obj->i2c == I2C_1) {
__I2C1_FORCE_RESET(); __I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET(); __I2C1_RELEASE_RESET();
} }
@ -263,7 +262,7 @@ int i2c_slave_receive(i2c_t *obj) {
int i2c_slave_read(i2c_t *obj, char *data, int length) { int i2c_slave_read(i2c_t *obj, char *data, int length) {
if (length == 0) return 0; if (length == 0) return 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Reception process with 5 seconds timeout // Reception process with 5 seconds timeout
@ -276,7 +275,7 @@ int i2c_slave_read(i2c_t *obj, char *data, int length) {
int i2c_slave_write(i2c_t *obj, const char *data, int length) { int i2c_slave_write(i2c_t *obj, const char *data, int length) {
if (length == 0) return 0; if (length == 0) return 0;
I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c); I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
// Transmission process with 5 seconds timeout // Transmission process with 5 seconds timeout

View File

@ -0,0 +1,34 @@
/* 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 "cmsis.h"
// This function is called after RAM initialization and before main.
void mbed_sdk_init() {
// Update the SystemCoreClock variable.
SystemCoreClockUpdate();
}

View File

@ -49,7 +49,7 @@ struct gpio_irq_s {
struct port_s { struct port_s {
PortName port; PortName port;
uint32_t mask; uint32_t mask;
PinDirection direction; PinDirection direction;
__IO uint32_t *reg_in; __IO uint32_t *reg_in;
__IO uint32_t *reg_out; __IO uint32_t *reg_out;
}; };
@ -65,7 +65,7 @@ struct serial_s {
uint32_t baudrate; uint32_t baudrate;
uint32_t databits; uint32_t databits;
uint32_t stopbits; uint32_t stopbits;
uint32_t parity; uint32_t parity;
}; };
struct spi_s { struct spi_s {

View File

@ -30,7 +30,6 @@
#include "pinmap.h" #include "pinmap.h"
#include "PortNames.h" #include "PortNames.h"
#include "error.h" #include "error.h"
#include "stm32f4xx_hal.h"
// GPIO mode look-up table // GPIO mode look-up table
static const uint32_t gpio_mode[12] = { static const uint32_t gpio_mode[12] = {
@ -74,7 +73,7 @@ uint32_t Set_GPIO_Clock(uint32_t port_idx) {
break; break;
default: default:
error("Pinmap error: wrong port number."); error("Pinmap error: wrong port number.");
break; break;
} }
return gpio_add; return gpio_add;
} }
@ -105,7 +104,7 @@ void pin_function(PinName pin, int data) {
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Alternate = afnum; GPIO_InitStructure.Alternate = afnum;
HAL_GPIO_Init(gpio, &GPIO_InitStructure); HAL_GPIO_Init(gpio, &GPIO_InitStructure);
// [TODO] Disconnect JTAG-DP + SW-DP signals. // [TODO] Disconnect JTAG-DP + SW-DP signals.
// Warning: Need to reconnect under reset // Warning: Need to reconnect under reset
//if ((pin == PA_13) || (pin == PA_14)) { //if ((pin == PA_13) || (pin == PA_14)) {
@ -113,7 +112,7 @@ void pin_function(PinName pin, int data) {
//} //}
//if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) { //if ((pin == PA_15) || (pin == PB_3) || (pin == PB_4)) {
// //
//} //}
} }
/** /**
@ -134,5 +133,5 @@ void pin_mode(PinName pin, PinMode mode) {
if (pupd > 2) pupd = 0; // Open-drain = No pull-up/No pull-down if (pupd > 2) pupd = 0; // Open-drain = No pull-up/No pull-down
gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2))); gpio->PUPDR &= (uint32_t)(~(GPIO_PUPDR_PUPDR0 << (pin_index * 2)));
gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2)); gpio->PUPDR |= (uint32_t)(pupd << (pin_index * 2));
} }

View File

@ -31,7 +31,6 @@
#include "pinmap.h" #include "pinmap.h"
#include "gpio_api.h" #include "gpio_api.h"
#include "error.h" #include "error.h"
#include "stm32f4xx_hal.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT #if DEVICE_PORTIN || DEVICE_PORTOUT
@ -40,7 +39,7 @@ 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, ...) // high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...)
// low nibble = pin number // low nibble = pin number
PinName port_pin(PortName port, int pin_n) { PinName port_pin(PortName port, int pin_n) {
return (PinName)(pin_n + (port << 4)); return (PinName)(pin_n + (port << 4));
} }
void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
@ -53,9 +52,9 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) {
// Fill PORT object structure for future use // Fill PORT object structure for future use
obj->port = port; obj->port = port;
obj->mask = mask; obj->mask = mask;
obj->direction = dir; obj->direction = dir;
obj->reg_in = &gpio->IDR; obj->reg_in = &gpio->IDR;
obj->reg_out = &gpio->ODR; obj->reg_out = &gpio->ODR;
port_dir(obj, dir); port_dir(obj, dir);
} }
@ -67,16 +66,15 @@ void port_dir(port_t *obj, PinDirection dir) {
if (obj->mask & (1 << i)) { // If the pin is used if (obj->mask & (1 << i)) { // If the pin is used
if (dir == PIN_OUTPUT) { if (dir == PIN_OUTPUT) {
pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_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
else { // PIN_INPUT
pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0)); pin_function(port_pin(obj->port, i), STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
} }
} }
} }
} }
void port_mode(port_t *obj, PinMode mode) { void port_mode(port_t *obj, PinMode mode) {
uint32_t i; uint32_t i;
for (i = 0; i < 16; i++) { // Process all pins for (i = 0; i < 16; i++) { // Process all pins
if (obj->mask & (1 << i)) { // If the pin is used if (obj->mask & (1 << i)) { // If the pin is used
pin_mode(port_pin(obj->port, i), mode); pin_mode(port_pin(obj->port, i), mode);
@ -91,8 +89,7 @@ void port_write(port_t *obj, int value) {
int port_read(port_t *obj) { int port_read(port_t *obj) {
if (obj->direction == PIN_OUTPUT) { if (obj->direction == PIN_OUTPUT) {
return (*obj->reg_out & obj->mask); return (*obj->reg_out & obj->mask);
} } else { // PIN_INPUT
else { // PIN_INPUT
return (*obj->reg_in & obj->mask); return (*obj->reg_in & obj->mask);
} }
} }

View File

@ -29,27 +29,28 @@
*/ */
#include "pwmout_api.h" #include "pwmout_api.h"
#if DEVICE_PWMOUT
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include "stm32f4xx_hal.h"
// TIM5 cannot be used because already used by the us_ticker // TIM5 cannot be used because already used by the us_ticker
static const PinMap PinMap_PWM[] = { static const PinMap PinMap_PWM[] = {
{PA_0, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1 {PA_0, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1
//{PA_0, PWM_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5)}, // TIM5_CH1 // {PA_0, PWM_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5)}, // TIM5_CH1
{PA_1, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH2 {PA_1, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH2
//{PA_1, PWM_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5)}, // TIM5_CH2 // {PA_1, PWM_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5)}, // TIM5_CH2
{PA_2, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH3 {PA_2, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH3
//{PA_2, PWM_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5)}, // TIM5_CH3 // {PA_2, PWM_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5)}, // TIM5_CH3
//{PA_2, PWM_9, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9)}, // TIM9_CH1 // {PA_2, PWM_9, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9)}, // TIM9_CH1
{PA_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH3 {PA_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH3
//{PA_3, PWM_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5)}, // TIM5_CH4 // {PA_3, PWM_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM5)}, // TIM5_CH4
//{PA_3, PWM_9, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9)}, // TIM9_CH2 // {PA_3, PWM_9, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM9)}, // TIM9_CH2
{PA_5, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1 {PA_5, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1
{PA_6, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH1 {PA_6, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH1
{PA_7, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH1N {PA_7, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH1N
//{PA_7, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH2 // {PA_7, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH2
{PA_8, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH1 {PA_8, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH1
{PA_9, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH2 {PA_9, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH2
{PA_10, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH3 {PA_10, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH3
@ -57,18 +58,18 @@ static const PinMap PinMap_PWM[] = {
{PA_15, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1 {PA_15, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH1
{PB_0, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH2N {PB_0, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH2N
//{PB_0, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH3 // {PB_0, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH3
{PB_1, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH3N {PB_1, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH3N
//{PB_1, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH4 // {PB_1, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH4
{PB_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH2 {PB_3, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH2
{PB_4, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH1 {PB_4, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH1
{PB_5, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH2 {PB_5, PWM_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM3)}, // TIM3_CH2
{PB_6, PWM_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4)}, // TIM4_CH1 {PB_6, PWM_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4)}, // TIM4_CH1
{PB_7, PWM_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4)}, // TIM4_CH2 {PB_7, PWM_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4)}, // TIM4_CH2
{PB_8, PWM_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4)}, // TIM4_CH3 {PB_8, PWM_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4)}, // TIM4_CH3
//{PB_8, PWM_10,STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10)}, // TIM10_CH1 // {PB_8, PWM_10,STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM10)}, // TIM10_CH1
{PB_9, PWM_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4)}, // TIM4_CH4 {PB_9, PWM_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4)}, // TIM4_CH4
//{PB_9, PWM_11,STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11)}, // TIM11_CH1 // {PB_9, PWM_11,STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF3_TIM11)}, // TIM11_CH1
{PB_10, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH3 {PB_10, PWM_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2)}, // TIM2_CH3
{PB_13, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH1N {PB_13, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH1N
{PB_14, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH2N {PB_14, PWM_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM1)}, // TIM1_CH2N
@ -84,14 +85,14 @@ static const PinMap PinMap_PWM[] = {
static TIM_HandleTypeDef TimHandle; static TIM_HandleTypeDef TimHandle;
void pwmout_init(pwmout_t* obj, PinName pin) { void pwmout_init(pwmout_t* obj, PinName pin) {
// Get the peripheral name from the pin and assign it to the object // Get the peripheral name from the pin and assign it to the object
obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); obj->pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
if (obj->pwm == (PWMName)NC) { if (obj->pwm == (PWMName)NC) {
error("PWM error: pinout mapping failed."); error("PWM error: pinout mapping failed.");
} }
// Enable TIM clock // Enable TIM clock
if (obj->pwm == PWM_1) __TIM1_CLK_ENABLE(); if (obj->pwm == PWM_1) __TIM1_CLK_ENABLE();
if (obj->pwm == PWM_2) __TIM2_CLK_ENABLE(); if (obj->pwm == PWM_2) __TIM2_CLK_ENABLE();
@ -100,23 +101,20 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
if (obj->pwm == PWM_9) __TIM9_CLK_ENABLE(); if (obj->pwm == PWM_9) __TIM9_CLK_ENABLE();
if (obj->pwm == PWM_10) __TIM10_CLK_ENABLE(); if (obj->pwm == PWM_10) __TIM10_CLK_ENABLE();
if (obj->pwm == PWM_11) __TIM11_CLK_ENABLE(); if (obj->pwm == PWM_11) __TIM11_CLK_ENABLE();
// Configure GPIO // Configure GPIO
pinmap_pinout(pin, PinMap_PWM); pinmap_pinout(pin, PinMap_PWM);
obj->pin = pin; obj->pin = pin;
obj->period = 0; obj->period = 0;
obj->pulse = 0; obj->pulse = 0;
pwmout_period_us(obj, 20000); // 20 ms per default pwmout_period_us(obj, 20000); // 20 ms per default
} }
void pwmout_free(pwmout_t* obj) { void pwmout_free(pwmout_t* obj) {
TimHandle.Instance = (TIM_TypeDef *)(obj->pwm); // Configure GPIO
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
HAL_TIM_PWM_DeInit(&TimHandle);
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
} }
void pwmout_write(pwmout_t* obj, float value) { void pwmout_write(pwmout_t* obj, float value) {
@ -125,20 +123,20 @@ void pwmout_write(pwmout_t* obj, float value) {
int complementary_channel = 0; int complementary_channel = 0;
TimHandle.Instance = (TIM_TypeDef *)(obj->pwm); TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
if (value < (float)0.0) { if (value < (float)0.0) {
value = 0.0; value = 0.0;
} else if (value > (float)1.0) { } else if (value > (float)1.0) {
value = 1.0; value = 1.0;
} }
obj->pulse = (uint32_t)((float)obj->period * value); obj->pulse = (uint32_t)((float)obj->period * value);
// Configure channels // Configure channels
sConfig.OCMode = TIM_OCMODE_PWM1; sConfig.OCMode = TIM_OCMODE_PWM1;
sConfig.Pulse = obj->pulse; sConfig.Pulse = obj->pulse;
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfig.OCFastMode = TIM_OCFAST_DISABLE; sConfig.OCFastMode = TIM_OCFAST_DISABLE;
sConfig.OCIdleState = TIM_OCIDLESTATE_RESET; sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET; sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
@ -146,16 +144,16 @@ void pwmout_write(pwmout_t* obj, float value) {
switch (obj->pin) { switch (obj->pin) {
// Channels 1 // Channels 1
case PA_0: case PA_0:
//case PA_2: // case PA_2:
case PA_5: case PA_5:
case PA_6: case PA_6:
case PA_8: case PA_8:
case PA_15: case PA_15:
case PB_4: case PB_4:
case PB_6: case PB_6:
//case PB_8: // case PB_8:
//case PB_9: // case PB_9:
case PC_6: case PC_6:
channel = TIM_CHANNEL_1; channel = TIM_CHANNEL_1;
break; break;
// Channels 1N // Channels 1N
@ -166,8 +164,8 @@ void pwmout_write(pwmout_t* obj, float value) {
break; break;
// Channels 2 // Channels 2
case PA_1: case PA_1:
//case PA_3: // case PA_3:
//case PA_7: // case PA_7:
case PA_9: case PA_9:
case PB_3: case PB_3:
case PB_5: case PB_5:
@ -177,7 +175,7 @@ void pwmout_write(pwmout_t* obj, float value) {
break; break;
// Channels 2N // Channels 2N
case PB_0: case PB_0:
case PB_14: case PB_14:
channel = TIM_CHANNEL_2; channel = TIM_CHANNEL_2;
complementary_channel = 1; complementary_channel = 1;
break; break;
@ -185,7 +183,7 @@ void pwmout_write(pwmout_t* obj, float value) {
case PA_2: case PA_2:
case PA_3: case PA_3:
case PA_10: case PA_10:
//case PB_0: // case PB_0:
case PB_8: case PB_8:
case PB_10: case PB_10:
case PC_8: case PC_8:
@ -198,17 +196,17 @@ void pwmout_write(pwmout_t* obj, float value) {
complementary_channel = 1; complementary_channel = 1;
break; break;
// Channels 4 // Channels 4
//case PA_3: // case PA_3:
case PA_11: case PA_11:
//case PB_1: // case PB_1:
case PB_9: case PB_9:
case PC_9: case PC_9:
channel = TIM_CHANNEL_4; channel = TIM_CHANNEL_4;
break; break;
default: default:
return; return;
} }
HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, channel); HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, channel);
if (complementary_channel) { if (complementary_channel) {
HAL_TIMEx_PWMN_Start(&TimHandle, channel); HAL_TIMEx_PWMN_Start(&TimHandle, channel);
@ -238,9 +236,9 @@ void pwmout_period_us(pwmout_t* obj, int us) {
TimHandle.Instance = (TIM_TypeDef *)(obj->pwm); TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
float dc = pwmout_read(obj); float dc = pwmout_read(obj);
__HAL_TIM_DISABLE(&TimHandle); __HAL_TIM_DISABLE(&TimHandle);
TimHandle.Init.Period = us - 1; TimHandle.Init.Period = us - 1;
TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
TimHandle.Init.ClockDivision = 0; TimHandle.Init.ClockDivision = 0;
@ -250,9 +248,9 @@ void pwmout_period_us(pwmout_t* obj, int us) {
// Set duty cycle again // Set duty cycle again
pwmout_write(obj, dc); pwmout_write(obj, dc);
// Save for future use // Save for future use
obj->period = us; obj->period = us;
__HAL_TIM_ENABLE(&TimHandle); __HAL_TIM_ENABLE(&TimHandle);
} }
@ -268,3 +266,5 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
float value = (float)us / (float)obj->period; float value = (float)us / (float)obj->period;
pwmout_write(obj, value); pwmout_write(obj, value);
} }
#endif

View File

@ -28,7 +28,9 @@
******************************************************************************* *******************************************************************************
*/ */
#include "rtc_api.h" #include "rtc_api.h"
#include "stm32f4xx_hal.h"
#if DEVICE_RTC
#include "error.h" #include "error.h"
static int rtc_inited = 0; static int rtc_inited = 0;
@ -36,6 +38,9 @@ static int rtc_inited = 0;
static RTC_HandleTypeDef RtcHandle; static RTC_HandleTypeDef RtcHandle;
void rtc_init(void) { void rtc_init(void) {
RCC_OscInitTypeDef RCC_OscInitStruct;
uint32_t rtc_freq = 0;
if (rtc_inited) return; if (rtc_inited) return;
rtc_inited = 1; rtc_inited = 1;
@ -44,41 +49,51 @@ void rtc_init(void) {
// Enable Power clock // Enable Power clock
__PWR_CLK_ENABLE(); __PWR_CLK_ENABLE();
// Allow access to RTC // Enable access to Backup domain
HAL_PWR_EnableBkUpAccess(); HAL_PWR_EnableBkUpAccess();
// Reset Backup domain // Reset Backup domain
__HAL_RCC_BACKUPRESET_FORCE(); __HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE(); __HAL_RCC_BACKUPRESET_RELEASE();
// Enable LSI clock // Enable LSE Oscillator
RCC_OscInitTypeDef RCC_OscInitStruct; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* Mandatory, otherwise the PLL is reconfigured! */
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.LSEState = RCC_LSE_ON; /* External 32.768 kHz clock on OSC_IN/OSC_OUT */
RCC_OscInitStruct.LSIState = RCC_LSI_ON; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK)
RCC_OscInitStruct.LSEState = RCC_LSE_OFF; {
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { // Connect LSE to RTC
error("RTC error: LSI clock initialization failed."); __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE);
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
rtc_freq = LSE_VALUE;
} else {
// Enable LSI clock
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
error("RTC error: LSI clock initialization failed.");
}
// Connect LSI to RTC
__HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
// [TODO] This value is LSI typical value. To be measured precisely using a timer input capture
rtc_freq = 32000;
} }
// Connect LSI to RTC // Enable RTC
__HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSI);
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
// Enable RTC clock
__HAL_RCC_RTC_ENABLE(); __HAL_RCC_RTC_ENABLE();
// [TODO] This value is LSI typical value. To be measured precisely using a timer input capture
uint32_t lsi_freq = 32000;
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
RtcHandle.Init.AsynchPrediv = 127; RtcHandle.Init.AsynchPrediv = 127;
RtcHandle.Init.SynchPrediv = (lsi_freq / 128) - 1; RtcHandle.Init.SynchPrediv = (rtc_freq / 128) - 1;
RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&RtcHandle) != HAL_OK) { if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
error("RTC error: RTC initialization failed."); error("RTC error: RTC initialization failed.");
} }
} }
@ -86,20 +101,24 @@ void rtc_free(void) {
// Enable Power clock // Enable Power clock
__PWR_CLK_ENABLE(); __PWR_CLK_ENABLE();
// Allow access to RTC // Enable access to Backup domain
HAL_PWR_EnableBkUpAccess(); HAL_PWR_EnableBkUpAccess();
// Reset Backup domain // Reset Backup domain
__HAL_RCC_BACKUPRESET_FORCE(); __HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE(); __HAL_RCC_BACKUPRESET_RELEASE();
// Disable LSI clock // Disable access to Backup domain
HAL_PWR_DisableBkUpAccess();
// Disable LSI and LSE clocks
RCC_OscInitTypeDef RCC_OscInitStruct; 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.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF; RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
HAL_RCC_OscConfig(&RCC_OscInitStruct); HAL_RCC_OscConfig(&RCC_OscInitStruct);
rtc_inited = 0; rtc_inited = 0;
} }
@ -128,14 +147,14 @@ time_t rtc_read(void) {
RTC_DateTypeDef dateStruct; RTC_DateTypeDef dateStruct;
RTC_TimeTypeDef timeStruct; RTC_TimeTypeDef timeStruct;
struct tm timeinfo; struct tm timeinfo;
RtcHandle.Instance = RTC; RtcHandle.Instance = RTC;
// Read actual date and time // Read actual date and time
// Warning: the time must be read first! // Warning: the time must be read first!
HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN); HAL_RTC_GetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN); HAL_RTC_GetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
// Setup a tm structure based on the RTC // Setup a tm structure based on the RTC
timeinfo.tm_wday = dateStruct.WeekDay; timeinfo.tm_wday = dateStruct.WeekDay;
timeinfo.tm_mon = dateStruct.Month - 1; timeinfo.tm_mon = dateStruct.Month - 1;
@ -144,11 +163,11 @@ time_t rtc_read(void) {
timeinfo.tm_hour = timeStruct.Hours; timeinfo.tm_hour = timeStruct.Hours;
timeinfo.tm_min = timeStruct.Minutes; timeinfo.tm_min = timeStruct.Minutes;
timeinfo.tm_sec = timeStruct.Seconds; timeinfo.tm_sec = timeStruct.Seconds;
// Convert to timestamp // Convert to timestamp
time_t t = mktime(&timeinfo); time_t t = mktime(&timeinfo);
return t; return t;
} }
void rtc_write(time_t t) { void rtc_write(time_t t) {
@ -156,10 +175,10 @@ void rtc_write(time_t t) {
RTC_TimeTypeDef timeStruct; RTC_TimeTypeDef timeStruct;
RtcHandle.Instance = RTC; RtcHandle.Instance = RTC;
// Convert the time into a tm // Convert the time into a tm
struct tm *timeinfo = localtime(&t); struct tm *timeinfo = localtime(&t);
// Fill RTC structures // Fill RTC structures
dateStruct.WeekDay = timeinfo->tm_wday; dateStruct.WeekDay = timeinfo->tm_wday;
dateStruct.Month = timeinfo->tm_mon + 1; dateStruct.Month = timeinfo->tm_mon + 1;
@ -171,8 +190,10 @@ void rtc_write(time_t t) {
timeStruct.TimeFormat = RTC_HOURFORMAT12_PM; timeStruct.TimeFormat = RTC_HOURFORMAT12_PM;
timeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; timeStruct.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
timeStruct.StoreOperation = RTC_STOREOPERATION_RESET; timeStruct.StoreOperation = RTC_STOREOPERATION_RESET;
// Change the RTC current date/time // Change the RTC current date/time
HAL_RTC_SetDate(&RtcHandle, &dateStruct, FORMAT_BIN); HAL_RTC_SetDate(&RtcHandle, &dateStruct, FORMAT_BIN);
HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN); HAL_RTC_SetTime(&RtcHandle, &timeStruct, FORMAT_BIN);
} }
#endif

View File

@ -28,11 +28,13 @@
******************************************************************************* *******************************************************************************
*/ */
#include "serial_api.h" #include "serial_api.h"
#if DEVICE_SERIAL
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include <string.h> #include <string.h>
#include "stm32f4xx_hal.h"
static const PinMap PinMap_UART_TX[] = { static const PinMap PinMap_UART_TX[] = {
{PA_2, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, {PA_2, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
@ -54,33 +56,33 @@ static const PinMap PinMap_UART_RX[] = {
#define UART_NUM (3) #define UART_NUM (3)
static uint32_t serial_irq_ids[UART_NUM] = {0}; static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0};
static uart_irq_handler irq_handler; static uart_irq_handler irq_handler;
UART_HandleTypeDef UartHandle; UART_HandleTypeDef UartHandle;
int stdio_uart_inited = 0; int stdio_uart_inited = 0;
serial_t stdio_uart; serial_t stdio_uart;
static void init_uart(serial_t *obj) { static void init_uart(serial_t *obj) {
UartHandle.Instance = (USART_TypeDef *)(obj->uart); UartHandle.Instance = (USART_TypeDef *)(obj->uart);
UartHandle.Init.BaudRate = obj->baudrate; UartHandle.Init.BaudRate = obj->baudrate;
UartHandle.Init.WordLength = obj->databits; UartHandle.Init.WordLength = obj->databits;
UartHandle.Init.StopBits = obj->stopbits; UartHandle.Init.StopBits = obj->stopbits;
UartHandle.Init.Parity = obj->parity; UartHandle.Init.Parity = obj->parity;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&UartHandle); HAL_UART_Init(&UartHandle);
} }
void serial_init(serial_t *obj, PinName tx, PinName rx) { void serial_init(serial_t *obj, PinName tx, PinName rx) {
// Determine the UART to use (UART_1, UART_2, ...) // Determine the UART to use (UART_1, UART_2, ...)
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
// Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object // Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx); obj->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
@ -98,18 +100,18 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
if (obj->uart == UART_6) { if (obj->uart == UART_6) {
__USART6_CLK_ENABLE(); __USART6_CLK_ENABLE();
} }
// Configure the UART pins // Configure the UART pins
pinmap_pinout(tx, PinMap_UART_TX); pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX); pinmap_pinout(rx, PinMap_UART_RX);
pin_mode(tx, PullUp); pin_mode(tx, PullUp);
pin_mode(rx, PullUp); pin_mode(rx, PullUp);
// Configure UART // Configure UART
obj->baudrate = 9600; obj->baudrate = 9600;
obj->databits = UART_WORDLENGTH_8B; obj->databits = UART_WORDLENGTH_8B;
obj->stopbits = UART_STOPBITS_1; obj->stopbits = UART_STOPBITS_1;
obj->parity = UART_PARITY_NONE; obj->parity = UART_PARITY_NONE;
init_uart(obj); init_uart(obj);
@ -117,13 +119,13 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
if (obj->uart == UART_1) obj->index = 0; if (obj->uart == UART_1) obj->index = 0;
if (obj->uart == UART_2) obj->index = 1; if (obj->uart == UART_2) obj->index = 1;
if (obj->uart == UART_6) obj->index = 2; if (obj->uart == UART_6) obj->index = 2;
// For stdio management // For stdio management
if (obj->uart == STDIO_UART) { if (obj->uart == STDIO_UART) {
stdio_uart_inited = 1; stdio_uart_inited = 1;
memcpy(&stdio_uart, obj, sizeof(serial_t)); memcpy(&stdio_uart, obj, sizeof(serial_t));
} }
} }
void serial_free(serial_t *obj) { void serial_free(serial_t *obj) {
@ -138,29 +140,27 @@ void serial_baud(serial_t *obj, int baudrate) {
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) {
if (data_bits == 8) { if (data_bits == 8) {
obj->databits = UART_WORDLENGTH_8B; obj->databits = UART_WORDLENGTH_8B;
} } else {
else {
obj->databits = UART_WORDLENGTH_9B; obj->databits = UART_WORDLENGTH_9B;
} }
switch (parity) { switch (parity) {
case ParityOdd: case ParityOdd:
case ParityForced0: case ParityForced0:
obj->parity = UART_PARITY_ODD; obj->parity = UART_PARITY_ODD;
break; break;
case ParityEven: case ParityEven:
case ParityForced1: case ParityForced1:
obj->parity = UART_PARITY_EVEN; obj->parity = UART_PARITY_EVEN;
break; break;
default: // ParityNone default: // ParityNone
obj->parity = UART_PARITY_NONE; obj->parity = UART_PARITY_NONE;
break; break;
} }
if (stop_bits == 2) { if (stop_bits == 2) {
obj->stopbits = UART_STOPBITS_2; obj->stopbits = UART_STOPBITS_2;
} } else {
else {
obj->stopbits = UART_STOPBITS_1; obj->stopbits = UART_STOPBITS_1;
} }
@ -171,10 +171,8 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
* INTERRUPTS HANDLING * INTERRUPTS HANDLING
******************************************************************************/ ******************************************************************************/
// Not part of mbed api
static void uart_irq(UARTName name, int id) { static void uart_irq(UARTName name, int id) {
UartHandle.Instance = (USART_TypeDef *)name; UartHandle.Instance = (USART_TypeDef *)name;
if (serial_irq_ids[id] != 0) { if (serial_irq_ids[id] != 0) {
if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) { if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_TC) != RESET) {
irq_handler(serial_irq_ids[id], TxIrq); irq_handler(serial_irq_ids[id], TxIrq);
@ -187,10 +185,15 @@ static void uart_irq(UARTName name, int id) {
} }
} }
// Not part of mbed api static void uart1_irq(void) {
static void uart1_irq(void) {uart_irq(UART_1, 0);} uart_irq(UART_1, 0);
static void uart2_irq(void) {uart_irq(UART_2, 1);} }
static void uart6_irq(void) {uart_irq(UART_6, 2);} static void uart2_irq(void) {
uart_irq(UART_2, 1);
}
static void uart6_irq(void) {
uart_irq(UART_6, 2);
}
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
irq_handler = handler; irq_handler = handler;
@ -200,54 +203,52 @@ void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
IRQn_Type irq_n = (IRQn_Type)0; IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0; uint32_t vector = 0;
UartHandle.Instance = (USART_TypeDef *)(obj->uart); UartHandle.Instance = (USART_TypeDef *)(obj->uart);
if (obj->uart == UART_1) { if (obj->uart == UART_1) {
irq_n = USART1_IRQn; irq_n = USART1_IRQn;
vector = (uint32_t)&uart1_irq; vector = (uint32_t)&uart1_irq;
} }
if (obj->uart == UART_2) { if (obj->uart == UART_2) {
irq_n = USART2_IRQn; irq_n = USART2_IRQn;
vector = (uint32_t)&uart2_irq; vector = (uint32_t)&uart2_irq;
} }
if (obj->uart == UART_6) { if (obj->uart == UART_6) {
irq_n = USART6_IRQn; irq_n = USART6_IRQn;
vector = (uint32_t)&uart6_irq; vector = (uint32_t)&uart6_irq;
} }
if (enable) { if (enable) {
if (irq == RxIrq) { if (irq == RxIrq) {
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE); __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
} } else { // TxIrq
else { // TxIrq
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC); __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC);
} }
NVIC_SetVector(irq_n, vector); NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n); NVIC_EnableIRQ(irq_n);
} else { // disable } else { // disable
int all_disabled = 0; int all_disabled = 0;
if (irq == RxIrq) { if (irq == RxIrq) {
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE); __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
// Check if TxIrq is disabled too // Check if TxIrq is disabled too
if ((UartHandle.Instance->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1; if ((UartHandle.Instance->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1;
} } else { // TxIrq
else { // TxIrq
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TXE); __HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TXE);
// Check if RxIrq is disabled too // Check if RxIrq is disabled too
if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; if ((UartHandle.Instance->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
} }
if (all_disabled) NVIC_DisableIRQ(irq_n); if (all_disabled) NVIC_DisableIRQ(irq_n);
} }
} }
/****************************************************************************** /******************************************************************************
@ -299,3 +300,5 @@ void serial_break_set(serial_t *obj) {
void serial_break_clear(serial_t *obj) { void serial_break_clear(serial_t *obj) {
} }
#endif

View File

@ -28,24 +28,24 @@
******************************************************************************* *******************************************************************************
*/ */
#include "sleep_api.h" #include "sleep_api.h"
#include "cmsis.h"
#include "stm32f4xx_hal.h"
// This function is in the system_stm32f4xx.c file #if DEVICE_SLEEP
extern void SystemClock_Config(void);
#include "cmsis.h"
static TIM_HandleTypeDef TimMasterHandle; static TIM_HandleTypeDef TimMasterHandle;
void sleep(void) void sleep(void) {
{
// Request to enter SLEEP mode // Request to enter SLEEP mode
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
} }
void deepsleep(void) void deepsleep(void) {
{
// Request to enter STOP mode with regulator in low power mode // Request to enter STOP mode with regulator in low power mode
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
// After wake-up from STOP reconfigure the PLL // After wake-up from STOP reconfigure the PLL
SystemClock_Config(); SetSysClock();
} }
#endif

View File

@ -35,12 +35,11 @@
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include "stm32f4xx_hal.h"
static const PinMap PinMap_SPI_MOSI[] = { static const PinMap PinMap_SPI_MOSI[] = {
{PA_7, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PA_7, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
{PB_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
//{PB_5, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, // {PB_5, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PB_15, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {PB_15, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PC_3, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {PC_3, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PC_12, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {PC_12, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
@ -50,7 +49,7 @@ static const PinMap PinMap_SPI_MOSI[] = {
static const PinMap PinMap_SPI_MISO[] = { static const PinMap PinMap_SPI_MISO[] = {
{PA_6, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PA_6, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
{PB_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_4, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
//{PB_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, // {PB_4, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PB_14, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {PB_14, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PC_2, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {PC_2, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PC_11, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {PC_11, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
@ -60,7 +59,7 @@ static const PinMap PinMap_SPI_MISO[] = {
static const PinMap PinMap_SPI_SCLK[] = { static const PinMap PinMap_SPI_SCLK[] = {
{PA_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PA_5, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
{PB_3, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {PB_3, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
//{PB_3, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, // {PB_3, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
{PB_10, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {PB_10, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PB_13, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {PB_13, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)},
{PC_10, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)}, {PC_10, SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_SPI3)},
@ -69,9 +68,9 @@ static const PinMap PinMap_SPI_SCLK[] = {
static const PinMap PinMap_SPI_SSEL[] = { static const PinMap PinMap_SPI_SSEL[] = {
{PA_4, SPI_1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF5_SPI1)}, {PA_4, SPI_1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF5_SPI1)},
//{PA_4, SPI_3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF6_SPI3)}, // {PA_4, SPI_3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF6_SPI3)},
{PA_15, SPI_1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF5_SPI1)}, {PA_15, SPI_1, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF5_SPI1)},
//{PA_15, SPI_3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF6_SPI3)}, // {PA_15, SPI_3, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF6_SPI3)},
{PB_9, SPI_2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF5_SPI2)}, {PB_9, SPI_2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF5_SPI2)},
{PB_12, SPI_2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF5_SPI2)}, {PB_12, SPI_2, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, GPIO_AF5_SPI2)},
{NC, NC, 0} {NC, NC, 0}
@ -81,7 +80,7 @@ static SPI_HandleTypeDef SpiHandle;
static void init_spi(spi_t *obj) { static void init_spi(spi_t *obj) {
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
__HAL_SPI_DISABLE(&SpiHandle); __HAL_SPI_DISABLE(&SpiHandle);
SpiHandle.Init.Mode = obj->mode; SpiHandle.Init.Mode = obj->mode;
@ -95,7 +94,7 @@ static void init_spi(spi_t *obj) {
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.NSS = obj->nss; SpiHandle.Init.NSS = obj->nss;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED; SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED;
HAL_SPI_Init(&SpiHandle); HAL_SPI_Init(&SpiHandle);
__HAL_SPI_ENABLE(&SpiHandle); __HAL_SPI_ENABLE(&SpiHandle);
@ -107,16 +106,16 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO); SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK); SPIName spi_sclk = (SPIName)pinmap_peripheral(sclk, PinMap_SPI_SCLK);
SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL); SPIName spi_ssel = (SPIName)pinmap_peripheral(ssel, PinMap_SPI_SSEL);
SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso); SPIName spi_data = (SPIName)pinmap_merge(spi_mosi, spi_miso);
SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel); SPIName spi_cntl = (SPIName)pinmap_merge(spi_sclk, spi_ssel);
obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl); obj->spi = (SPIName)pinmap_merge(spi_data, spi_cntl);
if (obj->spi == (SPIName)NC) { if (obj->spi == (SPIName)NC) {
error("SPI error: pinout mapping failed."); error("SPI error: pinout mapping failed.");
} }
// Enable SPI clock // Enable SPI clock
if (obj->spi == SPI_1) { if (obj->spi == SPI_1) {
__SPI1_CLK_ENABLE(); __SPI1_CLK_ENABLE();
@ -127,23 +126,22 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
if (obj->spi == SPI_3) { if (obj->spi == SPI_3) {
__SPI3_CLK_ENABLE(); __SPI3_CLK_ENABLE();
} }
// Configure the SPI pins // Configure the SPI pins
pinmap_pinout(mosi, PinMap_SPI_MOSI); pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO); pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK); pinmap_pinout(sclk, PinMap_SPI_SCLK);
// Save new values // Save new values
obj->bits = SPI_DATASIZE_8BIT; obj->bits = SPI_DATASIZE_8BIT;
obj->cpol = SPI_POLARITY_LOW; obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_1EDGE; obj->cpha = SPI_PHASE_1EDGE;
obj->br_presc = SPI_BAUDRATEPRESCALER_256; obj->br_presc = SPI_BAUDRATEPRESCALER_256;
if (ssel == NC) { // SW NSS Master mode if (ssel == NC) { // SW NSS Master mode
obj->mode = SPI_MODE_MASTER; obj->mode = SPI_MODE_MASTER;
obj->nss = SPI_NSS_SOFT; obj->nss = SPI_NSS_SOFT;
} } else { // Slave
else { // Slave
pinmap_pinout(ssel, PinMap_SPI_SSEL); pinmap_pinout(ssel, PinMap_SPI_SSEL);
obj->mode = SPI_MODE_SLAVE; obj->mode = SPI_MODE_SLAVE;
obj->nss = SPI_NSS_HARD_INPUT; obj->nss = SPI_NSS_HARD_INPUT;
@ -157,43 +155,41 @@ void spi_free(spi_t *obj) {
HAL_SPI_DeInit(&SpiHandle); HAL_SPI_DeInit(&SpiHandle);
} }
void spi_format(spi_t *obj, int bits, int mode, int slave) { void spi_format(spi_t *obj, int bits, int mode, int slave) {
// Save new values // Save new values
if (bits == 8) { if (bits == 8) {
obj->bits = SPI_DATASIZE_8BIT; obj->bits = SPI_DATASIZE_8BIT;
} } else {
else {
obj->bits = SPI_DATASIZE_16BIT; obj->bits = SPI_DATASIZE_16BIT;
} }
switch (mode) { switch (mode) {
case 0: case 0:
obj->cpol = SPI_POLARITY_LOW; obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_1EDGE; obj->cpha = SPI_PHASE_1EDGE;
break; break;
case 1: case 1:
obj->cpol = SPI_POLARITY_LOW; obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_2EDGE; obj->cpha = SPI_PHASE_2EDGE;
break; break;
case 2: case 2:
obj->cpol = SPI_POLARITY_HIGH; obj->cpol = SPI_POLARITY_HIGH;
obj->cpha = SPI_PHASE_1EDGE; obj->cpha = SPI_PHASE_1EDGE;
break; break;
default: default:
obj->cpol = SPI_POLARITY_HIGH; obj->cpol = SPI_POLARITY_HIGH;
obj->cpha = SPI_PHASE_2EDGE; obj->cpha = SPI_PHASE_2EDGE;
break; break;
} }
if (slave == 0) { if (slave == 0) {
obj->mode = SPI_MODE_MASTER; obj->mode = SPI_MODE_MASTER;
obj->nss = SPI_NSS_SOFT; obj->nss = SPI_NSS_SOFT;
} } else {
else {
obj->mode = SPI_MODE_SLAVE; obj->mode = SPI_MODE_SLAVE;
obj->nss = SPI_NSS_HARD_INPUT; obj->nss = SPI_NSS_HARD_INPUT;
} }
init_spi(obj); init_spi(obj);
} }
@ -201,26 +197,19 @@ void spi_frequency(spi_t *obj, int hz) {
// Note: The frequencies are obtained with SPI1 clock = 84 MHz (APB2 clock) // Note: The frequencies are obtained with SPI1 clock = 84 MHz (APB2 clock)
if (hz < 600000) { if (hz < 600000) {
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 330 kHz obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 330 kHz
} } else if ((hz >= 600000) && (hz < 1000000)) {
else if ((hz >= 600000) && (hz < 1000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 656 kHz obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 656 kHz
} } else if ((hz >= 1000000) && (hz < 2000000)) {
else if ((hz >= 1000000) && (hz < 2000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.3 MHz obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.3 MHz
} } else if ((hz >= 2000000) && (hz < 5000000)) {
else if ((hz >= 2000000) && (hz < 5000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.6 MHz obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.6 MHz
} } else if ((hz >= 5000000) && (hz < 10000000)) {
else if ((hz >= 5000000) && (hz < 10000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5.25 MHz obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5.25 MHz
} } else if ((hz >= 10000000) && (hz < 21000000)) {
else if ((hz >= 10000000) && (hz < 21000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 10.5 MHz obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 10.5 MHz
} } else if ((hz >= 21000000) && (hz < 42000000)) {
else if ((hz >= 21000000) && (hz < 42000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 21 MHz obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 21 MHz
} } else { // >= 42000000
else { // >= 42000000
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 42 MHz obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 42 MHz
} }
init_spi(obj); init_spi(obj);
@ -231,7 +220,7 @@ static inline int ssp_readable(spi_t *obj) {
SpiHandle.Instance = (SPI_TypeDef *)(obj->spi); SpiHandle.Instance = (SPI_TypeDef *)(obj->spi);
// Check if data is received // Check if data is received
status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0); status = ((__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) != RESET) ? 1 : 0);
return status; return status;
} }
static inline int ssp_writeable(spi_t *obj) { static inline int ssp_writeable(spi_t *obj) {
@ -267,11 +256,12 @@ int spi_master_write(spi_t *obj, int value) {
} }
int spi_slave_receive(spi_t *obj) { int spi_slave_receive(spi_t *obj) {
return (ssp_readable(obj) && !ssp_busy(obj)) ? (1) : (0); return (!ssp_busy(obj)) ? (1) : (0);
}; };
int spi_slave_read(spi_t *obj) { int spi_slave_read(spi_t *obj) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_readable(obj));
return (int)spi->DR; return (int)spi->DR;
} }

View File

@ -28,12 +28,11 @@
#include <stddef.h> #include <stddef.h>
#include "us_ticker_api.h" #include "us_ticker_api.h"
#include "PeripheralNames.h" #include "PeripheralNames.h"
#include "stm32f4xx_hal.h"
// 32-bit timer selection // 32-bit timer selection
#define TIM_MST TIM5 #define TIM_MST TIM5
#define TIM_MST_IRQ TIM5_IRQn #define TIM_MST_IRQ TIM5_IRQn
#define TIM_MST_RCC __TIM5_CLK_ENABLE() #define TIM_MST_RCC __TIM5_CLK_ENABLE()
static TIM_HandleTypeDef TimMasterHandle; static TIM_HandleTypeDef TimMasterHandle;
static int us_ticker_inited = 0; static int us_ticker_inited = 0;
@ -41,10 +40,10 @@ static int us_ticker_inited = 0;
void us_ticker_init(void) { void us_ticker_init(void) {
if (us_ticker_inited) return; if (us_ticker_inited) return;
us_ticker_inited = 1; us_ticker_inited = 1;
// Enable timer clock // Enable timer clock
TIM_MST_RCC; TIM_MST_RCC;
// Configure time base // Configure time base
TimMasterHandle.Instance = TIM_MST; TimMasterHandle.Instance = TIM_MST;
TimMasterHandle.Init.Period = 0xFFFFFFFF; TimMasterHandle.Init.Period = 0xFFFFFFFF;
@ -53,10 +52,10 @@ void us_ticker_init(void) {
TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TimMasterHandle.Init.RepetitionCounter = 0; TimMasterHandle.Init.RepetitionCounter = 0;
HAL_TIM_OC_Init(&TimMasterHandle); HAL_TIM_OC_Init(&TimMasterHandle);
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)us_ticker_irq_handler); NVIC_SetVector(TIM_MST_IRQ, (uint32_t)us_ticker_irq_handler);
NVIC_EnableIRQ(TIM_MST_IRQ); NVIC_EnableIRQ(TIM_MST_IRQ);
// Enable timer // Enable timer
HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1); HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
} }