Merge pull request #281 from bcostm/master

[NUCLEO_L152RE/F103RB] Add LSE configuration for RTC
pull/283/head^2
Bogdan Marinescu 2014-04-29 11:05:21 +01:00
commit 5bf985ebc6
35 changed files with 865 additions and 847 deletions

View File

@ -147,6 +147,10 @@
#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */ #endif /* HSI_VALUE */
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */
#endif
/** /**
* @brief STM32F10x Standard Peripheral Library version number * @brief STM32F10x Standard Peripheral Library version number
*/ */

View File

@ -94,6 +94,8 @@ extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Cloc
extern void SystemInit(void); extern void SystemInit(void);
extern void SystemCoreClockUpdate(void); extern void SystemCoreClockUpdate(void);
extern void SetSysClock(void);
/** /**
* @} * @}
*/ */

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_3 = (int)USART3_BASE UART_3 = (int)USART3_BASE
} UARTName; } UARTName;

View File

@ -26,13 +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 "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include "wait_api.h"
static const PinMap PinMap_ADC[] = { static const PinMap PinMap_ADC[] = {
{PA_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AIN, 0)}, // ADC12_IN0 {PA_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AIN, 0)}, // ADC12_IN0
@ -57,15 +57,14 @@ static const PinMap PinMap_ADC[] = {
int adc_inited = 0; int adc_inited = 0;
void analogin_init(analogin_t *obj, PinName pin) { void analogin_init(analogin_t *obj, PinName pin) {
ADC_TypeDef *adc;
ADC_TypeDef *adc;
ADC_InitTypeDef ADC_InitStructure; ADC_InitTypeDef ADC_InitStructure;
// 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->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) {
error("ADC pin mapping failed"); error("ADC pin mapping failed");
} }
// Configure GPIO // Configure GPIO
@ -80,12 +79,12 @@ void analogin_init(analogin_t *obj, PinName pin) {
// Get ADC registers structure address // Get ADC registers structure address
adc = (ADC_TypeDef *)(obj->adc); adc = (ADC_TypeDef *)(obj->adc);
// Enable ADC clock (14 MHz maximum) // Enable ADC clock (14 MHz maximum)
// PCLK2 = 64 MHz --> ADC clock = 64/6 = 10.666 MHz // PCLK2 = 64 MHz --> ADC clock = 64/6 = 10.666 MHz
RCC_ADCCLKConfig(RCC_PCLK2_Div6); RCC_ADCCLKConfig(RCC_PCLK2_Div6);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// Configure ADC // Configure ADC
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ScanConvMode = DISABLE;
@ -100,87 +99,87 @@ void analogin_init(analogin_t *obj, PinName pin) {
// Calibrate ADC // Calibrate ADC
ADC_ResetCalibration(adc); ADC_ResetCalibration(adc);
while(ADC_GetResetCalibrationStatus(adc)); while (ADC_GetResetCalibrationStatus(adc));
ADC_StartCalibration(adc); ADC_StartCalibration(adc);
while(ADC_GetCalibrationStatus(adc)); while (ADC_GetCalibrationStatus(adc));
} }
} }
static inline uint16_t adc_read(analogin_t *obj) { static inline uint16_t adc_read(analogin_t *obj) {
// Get ADC registers structure address // Get ADC registers structure address
ADC_TypeDef *adc = (ADC_TypeDef *)(obj->adc); ADC_TypeDef *adc = (ADC_TypeDef *)(obj->adc);
int channel = 0; int channel = 0;
// Configure ADC channel
switch (obj->pin) {
case PA_0:
channel = 0;
break;
case PA_1:
channel = 1;
break;
case PA_2:
channel = 2;
break;
case PA_3:
channel = 3;
break;
case PA_4:
channel = 4;
break;
case PA_5:
channel = 5;
break;
case PA_6:
channel = 6;
break;
case PA_7:
channel = 7;
break;
case PB_0:
channel = 8;
break;
case PB_1:
channel = 9;
break;
case PC_0:
channel = 10;
break;
case PC_1:
channel = 11;
break;
case PC_2:
channel = 12;
break;
case PC_3:
channel = 13;
break;
case PC_4:
channel = 14;
break;
case PC_5:
channel = 15;
break;
default:
return 0;
}
ADC_RegularChannelConfig(adc, channel, 1, ADC_SampleTime_7Cycles5); // Configure ADC channel
switch (obj->pin) {
ADC_SoftwareStartConvCmd(adc, ENABLE); // Start conversion case PA_0:
channel = 0;
while(ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion break;
case PA_1:
return(ADC_GetConversionValue(adc)); // Get conversion value channel = 1;
break;
case PA_2:
channel = 2;
break;
case PA_3:
channel = 3;
break;
case PA_4:
channel = 4;
break;
case PA_5:
channel = 5;
break;
case PA_6:
channel = 6;
break;
case PA_7:
channel = 7;
break;
case PB_0:
channel = 8;
break;
case PB_1:
channel = 9;
break;
case PC_0:
channel = 10;
break;
case PC_1:
channel = 11;
break;
case PC_2:
channel = 12;
break;
case PC_3:
channel = 13;
break;
case PC_4:
channel = 14;
break;
case PC_5:
channel = 15;
break;
default:
return 0;
}
ADC_RegularChannelConfig(adc, channel, 1, ADC_SampleTime_7Cycles5);
ADC_SoftwareStartConvCmd(adc, ENABLE); // Start conversion
while (ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion
return (ADC_GetConversionValue(adc)); // Get conversion value
} }
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

@ -37,15 +37,15 @@
#define DEVICE_INTERRUPTIN 1 #define DEVICE_INTERRUPTIN 1
#define DEVICE_ANALOGIN 1 #define DEVICE_ANALOGIN 1
#define DEVICE_ANALOGOUT 0 #define DEVICE_ANALOGOUT 0 // Not present on this device
#define DEVICE_SERIAL 1 #define DEVICE_SERIAL 1
#define DEVICE_I2C 1 #define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 0 #define DEVICE_I2CSLAVE 0 // Not yet supported
#define DEVICE_SPI 1 #define DEVICE_SPI 1
#define DEVICE_SPISLAVE 0 #define DEVICE_SPISLAVE 0 // Not yet supported
#define DEVICE_RTC 1 #define DEVICE_RTC 1
@ -63,7 +63,7 @@
#define DEVICE_STDIO_MESSAGES 1 #define DEVICE_STDIO_MESSAGES 1
//#define DEVICE_ERROR_RED 0 #define DEVICE_ERROR_RED 0
#include "objects.h" #include "objects.h"

View File

@ -33,7 +33,7 @@
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(GPIO_Mode_IN_FLOATING, 0)); pin_function(pin, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0));
@ -45,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);
@ -65,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(GPIO_Mode_Out_PP, 0)); pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_Out_PP, 0));
} } else { // PIN_INPUT
else { // PIN_INPUT
pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)); pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0));
} }
} }

View File

@ -29,7 +29,6 @@
*/ */
#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 "error.h" #include "error.h"
@ -53,30 +52,42 @@ 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 (EXTI_GetITStatus(pin) != RESET) if (EXTI_GetITStatus(pin) != RESET) {
{
EXTI_ClearITPendingBit(pin); EXTI_ClearITPendingBit(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 static void gpio_irq0(void) {
static void gpio_irq1(void) {handle_interrupt_in(1);} // EXTI line 1 handle_interrupt_in(0); // EXTI line 0
static void gpio_irq2(void) {handle_interrupt_in(2);} // EXTI line 2 }
static void gpio_irq3(void) {handle_interrupt_in(3);} // EXTI line 3 static void gpio_irq1(void) {
static void gpio_irq4(void) {handle_interrupt_in(4);} // EXTI line 4 handle_interrupt_in(1); // EXTI line 1
static void gpio_irq5(void) {handle_interrupt_in(5);} // EXTI lines 5 to 9 }
static void gpio_irq6(void) {handle_interrupt_in(6);} // EXTI lines 10 to 15 static void gpio_irq2(void) {
handle_interrupt_in(2); // EXTI line 2
}
static void gpio_irq3(void) {
handle_interrupt_in(3); // EXTI line 3
}
static void gpio_irq4(void) {
handle_interrupt_in(4); // EXTI line 4
}
static void gpio_irq5(void) {
handle_interrupt_in(5); // EXTI lines 5 to 9
}
static void gpio_irq6(void) {
handle_interrupt_in(6); // EXTI lines 10 to 15
}
extern uint32_t Set_GPIO_Clock(uint32_t port_idx); extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
@ -143,7 +154,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
// Enable GPIO clock // Enable GPIO clock
uint32_t gpio_add = Set_GPIO_Clock(port_index); uint32_t gpio_add = Set_GPIO_Clock(port_index);
// Enable AFIO clock // Enable AFIO clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
@ -151,13 +162,13 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
GPIO_EXTILineConfig(port_index, pin_index); GPIO_EXTILineConfig(port_index, pin_index);
// Configure EXTI line // Configure EXTI line
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); EXTI_Init(&EXTI_InitStructure);
// Enable and set EXTI interrupt to the lowest priority // Enable and set EXTI interrupt to the lowest priority
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = irq_n; NVIC_InitStructure.NVIC_IRQChannel = irq_n;
@ -165,7 +176,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); NVIC_Init(&NVIC_InitStructure);
NVIC_SetVector(irq_n, vector); NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n); NVIC_EnableIRQ(irq_n);
@ -176,9 +187,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;
} }
@ -189,47 +200,44 @@ void gpio_irq_free(gpio_irq_t *obj) {
// Disable EXTI line // Disable EXTI line
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure); EXTI_StructInit(&EXTI_InitStructure);
EXTI_Init(&EXTI_InitStructure); EXTI_Init(&EXTI_InitStructure);
obj->event = EDGE_NONE; obj->event = EDGE_NONE;
} }
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
uint32_t pin_index = channel_pin[obj->irq_index]; uint32_t pin_index = channel_pin[obj->irq_index];
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
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)) {
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
obj->event = EDGE_BOTH; obj->event = EDGE_BOTH;
} } else { // NONE or RISE
else { // NONE or RISE
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_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)) {
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
obj->event = EDGE_BOTH; obj->event = EDGE_BOTH;
} } else { // NONE or FALL
else { // NONE or FALL
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
obj->event = EDGE_FALL; obj->event = EDGE_FALL;
} }
} }
if (enable) { if (enable) {
EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_InitStructure.EXTI_LineCmd = ENABLE;
} } else {
else {
EXTI_InitStructure.EXTI_LineCmd = DISABLE; EXTI_InitStructure.EXTI_LineCmd = DISABLE;
} }
EXTI_Init(&EXTI_InitStructure); EXTI_Init(&EXTI_InitStructure);
} }

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

@ -36,8 +36,8 @@
#include "error.h" #include "error.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)
@ -55,19 +55,19 @@ static const PinMap PinMap_I2C_SCL[] = {
{NC, NC, 0} {NC, NC, 0}
}; };
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 pin mapping failed"); error("I2C pin mapping failed");
} }
// Enable I2C clock // Enable I2C clock
if (obj->i2c == I2C_1) { if (obj->i2c == I2C_1) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
} }
if (obj->i2c == I2C_2) { if (obj->i2c == I2C_2) {
@ -79,21 +79,21 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
pin_mode(scl, OpenDrain); pin_mode(scl, OpenDrain);
pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(sda, PinMap_I2C_SDA);
pin_mode(sda, OpenDrain); pin_mode(sda, 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) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
I2C_InitTypeDef I2C_InitStructure; I2C_InitTypeDef I2C_InitStructure;
if ((hz != 0) && (hz <= 400000)) { if ((hz != 0) && (hz <= 400000)) {
I2C_DeInit(i2c); I2C_DeInit(i2c);
// I2C configuration // I2C configuration
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
@ -102,7 +102,7 @@ void i2c_frequency(i2c_t *obj, int hz) {
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = hz; I2C_InitStructure.I2C_ClockSpeed = hz;
I2C_Init(i2c, &I2C_InitStructure); I2C_Init(i2c, &I2C_InitStructure);
I2C_Cmd(i2c, ENABLE); I2C_Cmd(i2c, ENABLE);
} }
} }
@ -110,30 +110,29 @@ 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;
I2C_ClearFlag(i2c, I2C_FLAG_AF); // Clear Acknowledge failure flag I2C_ClearFlag(i2c, I2C_FLAG_AF); // Clear Acknowledge failure flag
// Generate the START condition // Generate the START condition
I2C_GenerateSTART(i2c, ENABLE); I2C_GenerateSTART(i2c, ENABLE);
// Wait the START condition has been correctly sent // Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
//while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_MODE_SELECT) == ERROR) {
while (I2C_GetFlagStatus(i2c, I2C_FLAG_SB) == RESET) { while (I2C_GetFlagStatus(i2c, I2C_FLAG_SB) == RESET) {
timeout--; timeout--;
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);
I2C_GenerateSTOP(i2c, ENABLE); I2C_GenerateSTOP(i2c, ENABLE);
return 0; return 0;
} }
@ -142,24 +141,13 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
int timeout; int timeout;
int count; int count;
int value; int value;
if (length == 0) return 0; if (length == 0) return 0;
/*
// Wait until the bus is not busy anymore
timeout = LONG_TIMEOUT;
while (I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY) == SET) {
timeout--;
if (timeout == 0) {
return 0;
}
}
*/
i2c_start(obj); i2c_start(obj);
// Send slave address for read // Send slave address for read
I2C_Send7bitAddress(i2c, address, I2C_Direction_Receiver); I2C_Send7bitAddress(i2c, address, I2C_Direction_Receiver);
// Wait address is acknowledged // Wait address is acknowledged
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
@ -169,13 +157,13 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
return 0; return 0;
} }
} }
// Read all bytes except last one // Read all bytes except last one
for (count = 0; count < (length - 1); count++) { for (count = 0; count < (length - 1); count++) {
value = i2c_byte_read(obj, 0); value = i2c_byte_read(obj, 0);
data[count] = (char)value; data[count] = (char)value;
} }
// If not repeated start, send stop. // If not repeated start, send stop.
// Warning: must be done BEFORE the data is read. // Warning: must be done BEFORE the data is read.
if (stop) { if (stop) {
@ -185,7 +173,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
// Read the last byte // Read the last byte
value = i2c_byte_read(obj, 1); value = i2c_byte_read(obj, 1);
data[count] = (char)value; data[count] = (char)value;
return length; return length;
} }
@ -193,23 +181,12 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout; int timeout;
int count; int count;
/*
// Wait until the bus is not busy anymore
timeout = LONG_TIMEOUT;
while (I2C_GetFlagStatus(i2c, I2C_FLAG_BUSY) == SET) {
timeout--;
if (timeout == 0) {
return 0;
}
}
*/
i2c_start(obj); i2c_start(obj);
// Send slave address for write // Send slave address for write
I2C_Send7bitAddress(i2c, address, I2C_Direction_Transmitter); I2C_Send7bitAddress(i2c, address, I2C_Direction_Transmitter);
// Wait address is acknowledged // Wait address is acknowledged
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR) { while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR) {
@ -238,7 +215,7 @@ int i2c_byte_read(i2c_t *obj, int last) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint8_t data; uint8_t data;
int timeout; int timeout;
if (last) { if (last) {
// Don't acknowledge the last byte // Don't acknowledge the last byte
I2C_AcknowledgeConfig(i2c, DISABLE); I2C_AcknowledgeConfig(i2c, DISABLE);
@ -257,7 +234,7 @@ int i2c_byte_read(i2c_t *obj, int last) {
} }
data = I2C_ReceiveData(i2c); data = I2C_ReceiveData(i2c);
return (int)data; return (int)data;
} }
@ -268,27 +245,26 @@ int i2c_byte_write(i2c_t *obj, int data) {
I2C_SendData(i2c, (uint8_t)data); I2C_SendData(i2c, (uint8_t)data);
// Wait until the byte is transmitted // Wait until the byte is transmitted
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
//while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR) {
while ((I2C_GetFlagStatus(i2c, I2C_FLAG_TXE) == RESET) && while ((I2C_GetFlagStatus(i2c, I2C_FLAG_TXE) == RESET) &&
(I2C_GetFlagStatus(i2c, I2C_FLAG_BTF) == RESET)) { (I2C_GetFlagStatus(i2c, I2C_FLAG_BTF) == RESET)) {
timeout--; timeout--;
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) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
} }
if (obj->i2c == I2C_2) { if (obj->i2c == I2C_2) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
} }
} }
@ -297,7 +273,7 @@ void i2c_reset(i2c_t *obj) {
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg; uint16_t tmpreg;
// Get the old register value // Get the old register value
tmpreg = i2c->OAR1; tmpreg = i2c->OAR1;
// Reset address bits // Reset address bits
@ -319,29 +295,28 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver) #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj) { int i2c_slave_receive(i2c_t *obj) {
// TO BE DONE return (0);
return(0);
} }
int i2c_slave_read(i2c_t *obj, char *data, int length) { int i2c_slave_read(i2c_t *obj, char *data, int length) {
int count = 0; int count = 0;
// Read all bytes // Read all bytes
for (count = 0; count < length; count++) { for (count = 0; count < length; count++) {
data[count] = i2c_byte_read(obj, 0); data[count] = i2c_byte_read(obj, 0);
} }
return count; return count;
} }
int i2c_slave_write(i2c_t *obj, const char *data, int length) { int i2c_slave_write(i2c_t *obj, const char *data, int length) {
int count = 0; int count = 0;
// Write all bytes // Write all bytes
for (count = 0; count < length; count++) { for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]); i2c_byte_write(obj, data[count]);
} }
return count; return count;
} }

View File

@ -48,7 +48,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;
}; };
@ -64,7 +64,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

@ -34,16 +34,16 @@
// Alternate-function mapping // Alternate-function mapping
#define AF_NUM (10) #define AF_NUM (10)
static const uint32_t AF_mapping[AF_NUM] = { static const uint32_t AF_mapping[AF_NUM] = {
0, // 0 = No AF 0, // 0 = No AF
GPIO_Remap_SPI1, // 1 GPIO_Remap_SPI1, // 1
GPIO_Remap_I2C1, // 2 GPIO_Remap_I2C1, // 2
GPIO_Remap_USART1, // 3 GPIO_Remap_USART1, // 3
GPIO_Remap_USART2, // 4 GPIO_Remap_USART2, // 4
GPIO_PartialRemap_USART3, // 5 GPIO_PartialRemap_USART3, // 5
GPIO_PartialRemap_TIM1, // 6 GPIO_PartialRemap_TIM1, // 6
GPIO_PartialRemap_TIM3, // 7 GPIO_PartialRemap_TIM3, // 7
GPIO_FullRemap_TIM2, // 8 GPIO_FullRemap_TIM2, // 8
GPIO_FullRemap_TIM3 // 9 GPIO_FullRemap_TIM3 // 9
}; };
// Enable GPIO clock and return GPIO base address // Enable GPIO clock and return GPIO base address
@ -98,14 +98,14 @@ void pin_function(PinName pin, int data) {
if ((afnum > 0) && (afnum < AF_NUM)) { if ((afnum > 0) && (afnum < AF_NUM)) {
GPIO_PinRemapConfig(AF_mapping[afnum], ENABLE); GPIO_PinRemapConfig(AF_mapping[afnum], ENABLE);
} }
// Configure GPIO // Configure GPIO
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index); GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index);
GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)mode; GPIO_InitStructure.GPIO_Mode = (GPIOMode_TypeDef)mode;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(gpio, &GPIO_InitStructure); GPIO_Init(gpio, &GPIO_InitStructure);
// Disconnect JTAG-DP + SW-DP signals. // 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 +113,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)) {
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
} }
} }
/** /**
@ -121,7 +121,7 @@ void pin_function(PinName pin, int data) {
*/ */
void pin_mode(PinName pin, PinMode mode) { void pin_mode(PinName pin, PinMode mode) {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
if (pin == NC) return; if (pin == NC) return;
uint32_t port_index = STM_PORT(pin); uint32_t port_index = STM_PORT(pin);
@ -130,35 +130,34 @@ void pin_mode(PinName pin, PinMode mode) {
// 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;
// Configure open-drain and pull-up/down // Configure open-drain and pull-up/down
switch (mode) { switch (mode) {
case PullNone: case PullNone:
return; return;
case PullUp: case PullUp:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
break; break;
case PullDown: case PullDown:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
break; break;
case OpenDrain: case OpenDrain:
if (pin_index < 8) { if (pin_index < 8) {
if ((gpio->CRL & (0x03 << (pin_index * 4))) > 0) { // MODE bits = Output mode if ((gpio->CRL & (0x03 << (pin_index * 4))) > 0) { // MODE bits = Output mode
gpio->CRL |= (0x04 << (pin_index * 4)); // Set open-drain gpio->CRL |= (0x04 << (pin_index * 4)); // Set open-drain
}
} else {
if ((gpio->CRH & (0x03 << ((pin_index % 8) * 4))) > 0) { // MODE bits = Output mode
gpio->CRH |= (0x04 << ((pin_index % 8) * 4)); // Set open-drain
}
} }
} return;
else { default:
if ((gpio->CRH & (0x03 << ((pin_index % 8) * 4))) > 0) { // MODE bits = Output mode break;
gpio->CRH |= (0x04 << ((pin_index % 8) * 4)); // Set open-drain
}
}
return;
default:
break;
} }
// Configure GPIO // Configure GPIO
GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index); GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(gpio, &GPIO_InitStructure); GPIO_Init(gpio, &GPIO_InitStructure);
} }

View File

@ -28,18 +28,19 @@
******************************************************************************* *******************************************************************************
*/ */
#include "port_api.h" #include "port_api.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
#include "pinmap.h" #include "pinmap.h"
#include "gpio_api.h" #include "gpio_api.h"
#include "error.h" #include "error.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
extern uint32_t Set_GPIO_Clock(uint32_t port_idx); 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) {
@ -52,9 +53,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);
} }
@ -66,16 +67,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(GPIO_Mode_Out_PP, 0)); pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_Out_PP, 0));
} } else { // PIN_INPUT
else { // PIN_INPUT
pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 0)); pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_IN_FLOATING, 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);
@ -90,8 +90,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,6 +29,8 @@
*/ */
#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"
@ -40,7 +42,7 @@ static const PinMap PinMap_PWM[] = {
{PA_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM2_CH4 - Default (warning: not connected on D0 per default) {PA_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM2_CH4 - Default (warning: not connected on D0 per default)
{PA_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH1 - Default {PA_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH1 - Default
{PA_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH2 - Default {PA_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH2 - Default
//{PA_7, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 6)}, // TIM1_CH1N - GPIO_PartialRemap_TIM1 // {PA_7, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 6)}, // TIM1_CH1N - GPIO_PartialRemap_TIM1
{PA_8, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH1 - Default {PA_8, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH1 - Default
{PA_9, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH2 - Default {PA_9, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH2 - Default
{PA_10, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH3 - Default {PA_10, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH3 - Default
@ -48,22 +50,22 @@ static const PinMap PinMap_PWM[] = {
{PA_15, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 8)}, // TIM2_CH1_ETR - GPIO_FullRemap_TIM2 {PA_15, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 8)}, // TIM2_CH1_ETR - GPIO_FullRemap_TIM2
{PB_0, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH3 - Default {PB_0, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH3 - Default
//{PB_0, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 6)}, // TIM1_CH2N - GPIO_PartialRemap_TIM1 // {PB_0, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 6)}, // TIM1_CH2N - GPIO_PartialRemap_TIM1
{PB_1, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH4 - Default {PB_1, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM3_CH4 - Default
//{PB_1, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 6)}, // TIM1_CH3N - GPIO_PartialRemap_TIM1 // {PB_1, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 6)}, // TIM1_CH3N - GPIO_PartialRemap_TIM1
{PB_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 8)}, // TIM2_CH2 - GPIO_FullRemap_TIM2 {PB_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 8)}, // TIM2_CH2 - GPIO_FullRemap_TIM2
{PB_4, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 7)}, // TIM3_CH1 - GPIO_PartialRemap_TIM3 {PB_4, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 7)}, // TIM3_CH1 - GPIO_PartialRemap_TIM3
{PB_5, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 7)}, // TIM3_CH2 - GPIO_PartialRemap_TIM3 {PB_5, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 7)}, // TIM3_CH2 - GPIO_PartialRemap_TIM3
//{PB_6, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH1 - Default (used by ticker) // {PB_6, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH1 - Default (used by ticker)
//{PB_7, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH2 - Default (used by ticker) // {PB_7, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH2 - Default (used by ticker)
//{PB_8, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH3 - Default (used by ticker) // {PB_8, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH3 - Default (used by ticker)
//{PB_9, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH4 - Default (used by ticker) // {PB_9, PWM_4, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM4_CH4 - Default (used by ticker)
{PB_10, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 8)}, // TIM2_CH3 - GPIO_FullRemap_TIM2 {PB_10, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 8)}, // TIM2_CH3 - GPIO_FullRemap_TIM2
{PB_11, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 8)}, // TIM2_CH4 - GPIO_FullRemap_TIM2 {PB_11, PWM_2, STM_PIN_DATA(GPIO_Mode_AF_PP, 8)}, // TIM2_CH4 - GPIO_FullRemap_TIM2
{PB_13, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH1N - Default {PB_13, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH1N - Default
{PB_14, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH2N - Default {PB_14, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH2N - Default
{PB_15, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH3N - Default {PB_15, PWM_1, STM_PIN_DATA(GPIO_Mode_AF_PP, 0)}, // TIM1_CH3N - Default
{PC_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 9)}, // TIM3_CH1 - GPIO_FullRemap_TIM3 {PC_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 9)}, // TIM3_CH1 - GPIO_FullRemap_TIM3
{PC_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 9)}, // TIM3_CH2 - GPIO_FullRemap_TIM3 {PC_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 9)}, // TIM3_CH2 - GPIO_FullRemap_TIM3
{PC_8, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 9)}, // TIM3_CH3 - GPIO_FullRemap_TIM3 {PC_8, PWM_3, STM_PIN_DATA(GPIO_Mode_AF_PP, 9)}, // TIM3_CH3 - GPIO_FullRemap_TIM3
@ -71,27 +73,27 @@ static const PinMap PinMap_PWM[] = {
{NC, NC, 0} {NC, NC, 0}
}; };
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 pinout mapping failed"); error("PWM pinout mapping failed");
} }
// Enable TIM clock // Enable TIM clock
if (obj->pwm == PWM_1) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); if (obj->pwm == PWM_1) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
if (obj->pwm == PWM_2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); if (obj->pwm == PWM_2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
if (obj->pwm == PWM_3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); if (obj->pwm == PWM_3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
if (obj->pwm == PWM_4) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); if (obj->pwm == PWM_4) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, 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
} }
@ -103,15 +105,15 @@ void pwmout_free(pwmout_t* obj) {
void pwmout_write(pwmout_t* obj, float value) { void pwmout_write(pwmout_t* obj, float value) {
TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm); TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm);
TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure;
if (value < 0.0) { if (value < 0.0) {
value = 0.0; value = 0.0;
} else if (value > 1.0) { } else if (value > 1.0) {
value = 1.0; value = 1.0;
} }
obj->pulse = (uint32_t)((float)obj->period * value); obj->pulse = (uint32_t)((float)obj->period * value);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = obj->pulse; TIM_OCInitStructure.TIM_Pulse = obj->pulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
@ -126,14 +128,14 @@ void pwmout_write(pwmout_t* obj, float value) {
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 PC_6: case PC_6:
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC1Init(tim, &TIM_OCInitStructure); TIM_OC1Init(tim, &TIM_OCInitStructure);
break; break;
// Channels 1N // Channels 1N
//case PA_7: //case PA_7:
case PB_13: case PB_13:
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC1PreloadConfig(tim, TIM_OCPreload_Enable);
@ -145,52 +147,52 @@ void pwmout_write(pwmout_t* obj, float value) {
case PA_9: case PA_9:
case PB_3: case PB_3:
case PB_5: case PB_5:
//case PB_7: //case PB_7:
case PC_7: case PC_7:
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC2Init(tim, &TIM_OCInitStructure); TIM_OC2Init(tim, &TIM_OCInitStructure);
break; break;
// Channels 2N // Channels 2N
//case PB_0: //case PB_0:
case PB_14: case PB_14:
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC2Init(tim, &TIM_OCInitStructure); TIM_OC2Init(tim, &TIM_OCInitStructure);
break; break;
// Channels 3 // Channels 3
case PA_2: case PA_2:
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:
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC3Init(tim, &TIM_OCInitStructure); TIM_OC3Init(tim, &TIM_OCInitStructure);
break; break;
// Channels 3N // Channels 3N
//case PB_1: //case PB_1:
case PB_15: case PB_15:
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC3Init(tim, &TIM_OCInitStructure); TIM_OC3Init(tim, &TIM_OCInitStructure);
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 PB_11: case PB_11:
case PC_9: case PC_9:
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC4Init(tim, &TIM_OCInitStructure); TIM_OC4Init(tim, &TIM_OCInitStructure);
break; break;
default: default:
return; return;
} }
TIM_CtrlPWMOutputs(tim, ENABLE); TIM_CtrlPWMOutputs(tim, ENABLE);
} }
@ -215,20 +217,20 @@ void pwmout_period_us(pwmout_t* obj, int us) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
float dc = pwmout_read(obj); float dc = pwmout_read(obj);
TIM_Cmd(tim, DISABLE); TIM_Cmd(tim, DISABLE);
obj->period = us; obj->period = us;
TIM_TimeBaseStructure.TIM_Period = obj->period - 1; TIM_TimeBaseStructure.TIM_Period = obj->period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure); TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure);
// Set duty cycle again // Set duty cycle again
pwmout_write(obj, dc); pwmout_write(obj, dc);
TIM_ARRPreloadConfig(tim, ENABLE); TIM_ARRPreloadConfig(tim, ENABLE);
TIM_Cmd(tim, ENABLE); TIM_Cmd(tim, ENABLE);
} }
@ -244,3 +246,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

@ -29,40 +29,60 @@
*/ */
#include "rtc_api.h" #include "rtc_api.h"
#if DEVICE_RTC
#include "wait_api.h"
#define LSE_STARTUP_TIMEOUT ((uint16_t)700) // delay in ms
static int rtc_inited = 0; static int rtc_inited = 0;
void rtc_init(void) { void rtc_init(void) {
uint32_t StartUpCounter = 0;
uint32_t LSEStatus = 0;
uint32_t rtc_freq = 0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // Enable PWR and Backup clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // Enable PWR and Backup clock
PWR_BackupAccessCmd(ENABLE); // Allow access to Backup Domain PWR_BackupAccessCmd(ENABLE); // Allow access to Backup Domain
BKP_DeInit(); // Reset Backup Domain BKP_DeInit(); // Reset Backup Domain
// Uncomment these lines if you use the LSE // Enable LSE clock
// Enable LSE and wait till it's ready RCC_LSEConfig(RCC_LSE_ON);
//RCC_LSEConfig(RCC_LSE_ON);
//while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {} // Wait till LSE is ready
//RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select LSE as RTC Clock Source do {
LSEStatus = RCC_GetFlagStatus(RCC_FLAG_LSERDY);
// Uncomment these lines if you use the LSI wait_ms(1);
// Enable LSI and wait till it's ready StartUpCounter++;
RCC_LSICmd(ENABLE); } while ((LSEStatus == 0) && (StartUpCounter <= LSE_STARTUP_TIMEOUT));
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select LSI as RTC Clock Source if (StartUpCounter > LSE_STARTUP_TIMEOUT) {
// The LSE has not started, use LSI instead.
RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock // The RTC Clock may vary due to LSI frequency dispersion.
RCC_LSEConfig(RCC_LSE_OFF);
RCC_LSICmd(ENABLE); // Enable LSI
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select the RTC Clock Source
rtc_freq = 40000; // [TODO] To be measured precisely using a timer input capture
} else {
// The LSE has correctly started
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select the RTC Clock Source
rtc_freq = LSE_VALUE;
}
RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock
RTC_WaitForSynchro(); // Wait for RTC registers synchronization RTC_WaitForSynchro(); // Wait for RTC registers synchronization
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
// Set RTC period to 1 sec // Set RTC period to 1 sec
// For LSE: prescaler = RTCCLK/RTC period = 32768Hz/1Hz = 32768 RTC_SetPrescaler(rtc_freq - 1);
// For LSI: prescaler = RTCCLK/RTC period = 40000Hz/1Hz = 40000
RTC_SetPrescaler(39999);
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
rtc_inited = 1; rtc_inited = 1;
} }
@ -84,3 +104,5 @@ void rtc_write(time_t t) {
RTC_SetCounter(t); // Change the current time RTC_SetCounter(t); // Change the current time
RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished RTC_WaitForLastTask(); // Wait until last write operation on RTC registers has finished
} }
#endif

View File

@ -28,6 +28,9 @@
******************************************************************************* *******************************************************************************
*/ */
#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"
@ -63,7 +66,7 @@ serial_t stdio_uart;
static void init_usart(serial_t *obj) { static void init_usart(serial_t *obj) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
USART_InitTypeDef USART_InitStructure; USART_InitTypeDef USART_InitStructure;
USART_Cmd(usart, DISABLE); USART_Cmd(usart, DISABLE);
USART_InitStructure.USART_BaudRate = obj->baudrate; USART_InitStructure.USART_BaudRate = obj->baudrate;
@ -73,15 +76,15 @@ static void init_usart(serial_t *obj) {
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(usart, &USART_InitStructure); USART_Init(usart, &USART_InitStructure);
USART_Cmd(usart, ENABLE); USART_Cmd(usart, ENABLE);
} }
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);
@ -91,15 +94,15 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
// Enable USART clock // Enable USART clock
if (obj->uart == UART_1) { if (obj->uart == UART_1) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
} }
if (obj->uart == UART_2) { if (obj->uart == UART_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
} }
if (obj->uart == UART_3) { if (obj->uart == UART_3) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, 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);
@ -108,7 +111,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
obj->baudrate = 9600; obj->baudrate = 9600;
obj->databits = USART_WordLength_8b; obj->databits = USART_WordLength_8b;
obj->stopbits = USART_StopBits_1; obj->stopbits = USART_StopBits_1;
obj->parity = USART_Parity_No; obj->parity = USART_Parity_No;
init_usart(obj); init_usart(obj);
@ -116,13 +119,12 @@ 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_3) obj->index = 2; if (obj->uart == UART_3) 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) {
@ -137,29 +139,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 = USART_WordLength_8b; obj->databits = USART_WordLength_8b;
} } else {
else {
obj->databits = USART_WordLength_9b; obj->databits = USART_WordLength_9b;
} }
switch (parity) { switch (parity) {
case ParityOdd: case ParityOdd:
case ParityForced0: case ParityForced0:
obj->parity = USART_Parity_Odd; obj->parity = USART_Parity_Odd;
break; break;
case ParityEven: case ParityEven:
case ParityForced1: case ParityForced1:
obj->parity = USART_Parity_Even; obj->parity = USART_Parity_Even;
break; break;
default: // ParityNone default: // ParityNone
obj->parity = USART_Parity_No; obj->parity = USART_Parity_No;
break; break;
} }
if (stop_bits == 2) { if (stop_bits == 2) {
obj->stopbits = USART_StopBits_2; obj->stopbits = USART_StopBits_2;
} } else {
else {
obj->stopbits = USART_StopBits_1; obj->stopbits = USART_StopBits_1;
} }
@ -205,50 +205,48 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); USART_TypeDef *usart = (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_3) { if (obj->uart == UART_3) {
irq_n = USART3_IRQn; irq_n = USART3_IRQn;
vector = (uint32_t)&uart3_irq; vector = (uint32_t)&uart3_irq;
} }
if (enable) { if (enable) {
if (irq == RxIrq) { if (irq == RxIrq) {
USART_ITConfig(usart, USART_IT_RXNE, ENABLE); USART_ITConfig(usart, USART_IT_RXNE, ENABLE);
} } else { // TxIrq
else { // TxIrq
USART_ITConfig(usart, USART_IT_TC, ENABLE); USART_ITConfig(usart, USART_IT_TC, ENABLE);
} }
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) {
USART_ITConfig(usart, USART_IT_RXNE, DISABLE); USART_ITConfig(usart, USART_IT_RXNE, DISABLE);
// Check if TxIrq is disabled too // Check if TxIrq is disabled too
if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1; if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1;
} } else { // TxIrq
else { // TxIrq
USART_ITConfig(usart, USART_IT_TXE, DISABLE); USART_ITConfig(usart, USART_IT_TXE, DISABLE);
// Check if RxIrq is disabled too // Check if RxIrq is disabled too
if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
} }
if (all_disabled) NVIC_DisableIRQ(irq_n); if (all_disabled) NVIC_DisableIRQ(irq_n);
} }
} }
/****************************************************************************** /******************************************************************************
@ -300,3 +298,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,37 +28,37 @@
******************************************************************************* *******************************************************************************
*/ */
#include "sleep_api.h" #include "sleep_api.h"
#if DEVICE_SLEEP
#include "cmsis.h" #include "cmsis.h"
// This function is in the system_stm32f10x.c file void sleep(void) {
extern void SetSysClock(void);
void sleep(void)
{
// Disable us_ticker update interrupt // Disable us_ticker update interrupt
TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE); TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE);
SCB->SCR = 0; // Normal sleep mode for ARM core SCB->SCR = 0; // Normal sleep mode for ARM core
__WFI(); __WFI();
// Re-enable us_ticker update interrupt // Re-enable us_ticker update interrupt
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
} }
void deepsleep(void) void deepsleep(void) {
{
// Disable us_ticker update interrupt // Disable us_ticker update interrupt
TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE); TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE);
// Enable PWR clock // Enable PWR clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
// Request to enter STOP mode with regulator in low power mode // Request to enter STOP mode with regulator in low power mode
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
// After wake-up from STOP reconfigure the PLL // After wake-up from STOP reconfigure the PLL
SetSysClock(); SetSysClock();
// Re-enable us_ticker update interrupt // Re-enable us_ticker update interrupt
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
} }
#endif

View File

@ -72,7 +72,7 @@ static void init_spi(spi_t *obj) {
SPI_InitStructure.SPI_Mode = obj->mode; SPI_InitStructure.SPI_Mode = obj->mode;
SPI_InitStructure.SPI_NSS = obj->nss; SPI_InitStructure.SPI_NSS = obj->nss;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = obj->bits; SPI_InitStructure.SPI_DataSize = obj->bits;
SPI_InitStructure.SPI_CPOL = obj->cpol; SPI_InitStructure.SPI_CPOL = obj->cpol;
SPI_InitStructure.SPI_CPHA = obj->cpha; SPI_InitStructure.SPI_CPHA = obj->cpha;
@ -90,19 +90,19 @@ 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 pinout mapping failed"); error("SPI pinout mapping failed");
} }
// Enable SPI clock // Enable SPI clock
if (obj->spi == SPI_1) { if (obj->spi == SPI_1) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
} }
if (obj->spi == SPI_2) { if (obj->spi == SPI_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
@ -112,18 +112,17 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
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_8b; obj->bits = SPI_DataSize_8b;
obj->cpol = SPI_CPOL_Low; obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_1Edge; obj->cpha = SPI_CPHA_1Edge;
obj->br_presc = SPI_BaudRatePrescaler_256; obj->br_presc = SPI_BaudRatePrescaler_256;
if (ssel == NC) { // Master if (ssel == NC) { // Master
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_Soft; obj->nss = SPI_NSS_Soft;
@ -137,43 +136,41 @@ void spi_free(spi_t *obj) {
SPI_I2S_DeInit(spi); SPI_I2S_DeInit(spi);
} }
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_8b; obj->bits = SPI_DataSize_8b;
} } else {
else {
obj->bits = SPI_DataSize_16b; obj->bits = SPI_DataSize_16b;
} }
switch (mode) { switch (mode) {
case 0: case 0:
obj->cpol = SPI_CPOL_Low; obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_1Edge; obj->cpha = SPI_CPHA_1Edge;
break; break;
case 1: case 1:
obj->cpol = SPI_CPOL_Low; obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_2Edge; obj->cpha = SPI_CPHA_2Edge;
break; break;
case 2: case 2:
obj->cpol = SPI_CPOL_High; obj->cpol = SPI_CPOL_High;
obj->cpha = SPI_CPHA_1Edge; obj->cpha = SPI_CPHA_1Edge;
break; break;
default: default:
obj->cpol = SPI_CPOL_High; obj->cpol = SPI_CPOL_High;
obj->cpha = SPI_CPHA_2Edge; obj->cpha = SPI_CPHA_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; obj->nss = SPI_NSS_Hard;
} }
init_spi(obj); init_spi(obj);
} }
@ -182,54 +179,40 @@ void spi_frequency(spi_t *obj, int hz) {
// Values depend of PCLK2: 64 MHz if HSI is used, 72 MHz if HSE is used // Values depend of PCLK2: 64 MHz if HSI is used, 72 MHz if HSE is used
if (hz < 500000) { if (hz < 500000) {
obj->br_presc = SPI_BaudRatePrescaler_256; // 250 kHz - 281 kHz obj->br_presc = SPI_BaudRatePrescaler_256; // 250 kHz - 281 kHz
} } else if ((hz >= 500000) && (hz < 1000000)) {
else if ((hz >= 500000) && (hz < 1000000)) {
obj->br_presc = SPI_BaudRatePrescaler_128; // 500 kHz - 563 kHz obj->br_presc = SPI_BaudRatePrescaler_128; // 500 kHz - 563 kHz
} } else if ((hz >= 1000000) && (hz < 2000000)) {
else if ((hz >= 1000000) && (hz < 2000000)) {
obj->br_presc = SPI_BaudRatePrescaler_64; // 1 MHz - 1.13 MHz obj->br_presc = SPI_BaudRatePrescaler_64; // 1 MHz - 1.13 MHz
} } else if ((hz >= 2000000) && (hz < 4000000)) {
else if ((hz >= 2000000) && (hz < 4000000)) {
obj->br_presc = SPI_BaudRatePrescaler_32; // 2 MHz - 2.25 MHz obj->br_presc = SPI_BaudRatePrescaler_32; // 2 MHz - 2.25 MHz
} } else if ((hz >= 4000000) && (hz < 8000000)) {
else if ((hz >= 4000000) && (hz < 8000000)) {
obj->br_presc = SPI_BaudRatePrescaler_16; // 4 MHz - 4.5 MHz obj->br_presc = SPI_BaudRatePrescaler_16; // 4 MHz - 4.5 MHz
} } else if ((hz >= 8000000) && (hz < 16000000)) {
else if ((hz >= 8000000) && (hz < 16000000)) {
obj->br_presc = SPI_BaudRatePrescaler_8; // 8 MHz - 9 MHz obj->br_presc = SPI_BaudRatePrescaler_8; // 8 MHz - 9 MHz
} } else if ((hz >= 16000000) && (hz < 32000000)) {
else if ((hz >= 16000000) && (hz < 32000000)) {
obj->br_presc = SPI_BaudRatePrescaler_4; // 16 MHz - 18 MHz obj->br_presc = SPI_BaudRatePrescaler_4; // 16 MHz - 18 MHz
} } else { // >= 32000000
else { // >= 32000000
obj->br_presc = SPI_BaudRatePrescaler_2; // 32 MHz - 36 MHz obj->br_presc = SPI_BaudRatePrescaler_2; // 32 MHz - 36 MHz
} }
} }
if (obj->spi == SPI_2) { if (obj->spi == SPI_2) {
// Values depend of PCLK1: 32 MHz if HSI is used, 36 MHz if HSE is used // Values depend of PCLK1: 32 MHz if HSI is used, 36 MHz if HSE is used
if (hz < 250000) { if (hz < 250000) {
obj->br_presc = SPI_BaudRatePrescaler_256; // 125 kHz - 141 kHz obj->br_presc = SPI_BaudRatePrescaler_256; // 125 kHz - 141 kHz
} } else if ((hz >= 250000) && (hz < 500000)) {
else if ((hz >= 250000) && (hz < 500000)) {
obj->br_presc = SPI_BaudRatePrescaler_128; // 250 kHz - 281 kHz obj->br_presc = SPI_BaudRatePrescaler_128; // 250 kHz - 281 kHz
} } else if ((hz >= 500000) && (hz < 1000000)) {
else if ((hz >= 500000) && (hz < 1000000)) {
obj->br_presc = SPI_BaudRatePrescaler_64; // 500 kHz - 563 kHz obj->br_presc = SPI_BaudRatePrescaler_64; // 500 kHz - 563 kHz
} } else if ((hz >= 1000000) && (hz < 2000000)) {
else if ((hz >= 1000000) && (hz < 2000000)) {
obj->br_presc = SPI_BaudRatePrescaler_32; // 1 MHz - 1.13 MHz obj->br_presc = SPI_BaudRatePrescaler_32; // 1 MHz - 1.13 MHz
} } else if ((hz >= 2000000) && (hz < 4000000)) {
else if ((hz >= 2000000) && (hz < 4000000)) {
obj->br_presc = SPI_BaudRatePrescaler_16; // 2 MHz - 2.25 MHz obj->br_presc = SPI_BaudRatePrescaler_16; // 2 MHz - 2.25 MHz
} } else if ((hz >= 4000000) && (hz < 8000000)) {
else if ((hz >= 4000000) && (hz < 8000000)) {
obj->br_presc = SPI_BaudRatePrescaler_8; // 4 MHz - 4.5 MHz obj->br_presc = SPI_BaudRatePrescaler_8; // 4 MHz - 4.5 MHz
} } else if ((hz >= 8000000) && (hz < 16000000)) {
else if ((hz >= 8000000) && (hz < 16000000)) {
obj->br_presc = SPI_BaudRatePrescaler_4; // 8 MHz - 9 MHz obj->br_presc = SPI_BaudRatePrescaler_4; // 8 MHz - 9 MHz
} } else { // >= 16000000
else { // >= 16000000
obj->br_presc = SPI_BaudRatePrescaler_2; // 16 MHz - 18 MHz obj->br_presc = SPI_BaudRatePrescaler_2; // 16 MHz - 18 MHz
} }
} }
@ -242,7 +225,7 @@ static inline int ssp_readable(spi_t *obj) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
// Check if data is received // Check if data is received
status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_RXNE) != RESET) ? 1 : 0); status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_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) {
@ -254,13 +237,13 @@ static inline int ssp_writeable(spi_t *obj) {
} }
static inline void ssp_write(spi_t *obj, int value) { static inline void ssp_write(spi_t *obj, int value) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_writeable(obj)); while (!ssp_writeable(obj));
SPI_I2S_SendData(spi, (uint16_t)value); SPI_I2S_SendData(spi, (uint16_t)value);
} }
static inline int ssp_read(spi_t *obj) { static inline int ssp_read(spi_t *obj) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_readable(obj)); while (!ssp_readable(obj));
return (int)SPI_I2S_ReceiveData(spi); return (int)SPI_I2S_ReceiveData(spi);
} }
@ -287,8 +270,8 @@ int spi_slave_read(spi_t *obj) {
} }
void spi_slave_write(spi_t *obj, int value) { void spi_slave_write(spi_t *obj, int value) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_writeable(obj)); while (!ssp_writeable(obj));
SPI_I2S_SendData(spi, (uint16_t)value); SPI_I2S_SendData(spi, (uint16_t)value);
} }

View File

@ -59,14 +59,12 @@ static void tim_irq_handler(void) {
if (oc_rem_part > 0) { if (oc_rem_part > 0) {
set_compare(oc_rem_part); // Finish the remaining time left set_compare(oc_rem_part); // Finish the remaining time left
oc_rem_part = 0; oc_rem_part = 0;
} } else {
else {
if (oc_int_part > 0) { if (oc_int_part > 0) {
set_compare(0xFFFF); set_compare(0xFFFF);
oc_rem_part = cval; // To finish the counter loop the next time oc_rem_part = cval; // To finish the counter loop the next time
oc_int_part--; oc_int_part--;
} } else {
else {
us_ticker_irq_handler(); us_ticker_irq_handler();
} }
} }
@ -75,13 +73,13 @@ static void tim_irq_handler(void) {
void us_ticker_init(void) { void us_ticker_init(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
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
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
@ -89,15 +87,15 @@ void us_ticker_init(void) {
TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM_MST, &TIM_TimeBaseStructure); TIM_TimeBaseInit(TIM_MST, &TIM_TimeBaseStructure);
// Configure interrupts // Configure interrupts
TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM_MST, TIM_IT_Update, ENABLE);
// Update interrupt used for 32-bit counter // Update interrupt used for 32-bit counter
// Output compare interrupt used for timeout feature // Output compare interrupt used for timeout feature
NVIC_SetVector(TIM_MST_IRQ, (uint32_t)tim_irq_handler); NVIC_SetVector(TIM_MST_IRQ, (uint32_t)tim_irq_handler);
NVIC_EnableIRQ(TIM_MST_IRQ); NVIC_EnableIRQ(TIM_MST_IRQ);
// Enable timer // Enable timer
TIM_Cmd(TIM_MST, ENABLE); TIM_Cmd(TIM_MST, ENABLE);
} }
@ -129,8 +127,7 @@ void us_ticker_set_interrupt(unsigned int timestamp) {
if (delta <= 0) { // This event was in the past if (delta <= 0) { // This event was in the past
us_ticker_irq_handler(); us_ticker_irq_handler();
} } else {
else {
oc_int_part = (uint32_t)(delta >> 16); oc_int_part = (uint32_t)(delta >> 16);
oc_rem_part = (uint16_t)(delta & 0xFFFF); oc_rem_part = (uint16_t)(delta & 0xFFFF);
if (oc_rem_part <= (0xFFFF - cval)) { if (oc_rem_part <= (0xFFFF - cval)) {

View File

@ -45,7 +45,7 @@ typedef enum {
} DACName; } DACName;
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_3 = (int)USART3_BASE, UART_3 = (int)USART3_BASE,
UART_4 = (int)UART4_BASE, UART_4 = (int)UART4_BASE,

View File

@ -26,13 +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 "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include "wait_api.h"
static const PinMap PinMap_ADC[] = { static const PinMap PinMap_ADC[] = {
{PA_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN0 {PA_0, ADC_1, STM_PIN_DATA(GPIO_Mode_AN, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)}, // ADC_IN0
@ -63,12 +63,12 @@ int adc_inited = 0;
void analogin_init(analogin_t *obj, PinName pin) { void analogin_init(analogin_t *obj, PinName pin) {
ADC_TypeDef *adc; ADC_TypeDef *adc;
ADC_InitTypeDef ADC_InitStructure; ADC_InitTypeDef ADC_InitStructure;
// 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->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) {
error("ADC pin mapping failed"); error("ADC pin mapping failed");
} }
// Configure GPIO // Configure GPIO
@ -83,10 +83,10 @@ void analogin_init(analogin_t *obj, PinName pin) {
// Get ADC registers structure address // Get ADC registers structure address
adc = (ADC_TypeDef *)(obj->adc); adc = (ADC_TypeDef *)(obj->adc);
// Enable ADC clock // Enable ADC clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// Configure ADC // Configure ADC
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ScanConvMode = DISABLE;
@ -103,92 +103,92 @@ void analogin_init(analogin_t *obj, PinName pin) {
} }
static inline uint16_t adc_read(analogin_t *obj) { static inline uint16_t adc_read(analogin_t *obj) {
// Get ADC registers structure address // Get ADC registers structure address
ADC_TypeDef *adc = (ADC_TypeDef *)(obj->adc); ADC_TypeDef *adc = (ADC_TypeDef *)(obj->adc);
uint8_t channel = 0; uint8_t channel = 0;
// Configure ADC channel
switch (obj->pin) {
case PA_0:
channel = ADC_Channel_0;
break;
case PA_1:
channel = ADC_Channel_1;
break;
case PA_2:
channel = ADC_Channel_2;
break;
case PA_3:
channel = ADC_Channel_3;
break;
case PA_4:
channel = ADC_Channel_4;
break;
case PA_5:
channel = ADC_Channel_5;
break;
case PA_6:
channel = ADC_Channel_6;
break;
case PA_7:
channel = ADC_Channel_7;
break;
case PB_0:
channel = ADC_Channel_8;
break;
case PB_1:
channel = ADC_Channel_9;
break;
case PB_12:
channel = ADC_Channel_18;
break;
case PB_13:
channel = ADC_Channel_19;
break;
case PB_14:
channel = ADC_Channel_20;
break;
case PB_15:
channel = ADC_Channel_21;
break;
case PC_0:
channel = ADC_Channel_10;
break;
case PC_1:
channel = ADC_Channel_11;
break;
case PC_2:
channel = ADC_Channel_12;
break;
case PC_3:
channel = ADC_Channel_13;
break;
case PC_4:
channel = ADC_Channel_14;
break;
case PC_5:
channel = ADC_Channel_15;
break;
default:
return 0;
}
ADC_RegularChannelConfig(adc, channel, 1, ADC_SampleTime_4Cycles); // Configure ADC channel
switch (obj->pin) {
ADC_SoftwareStartConv(adc); // Start conversion case PA_0:
channel = ADC_Channel_0;
while(ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion break;
case PA_1:
return(ADC_GetConversionValue(adc)); // Get conversion value channel = ADC_Channel_1;
break;
case PA_2:
channel = ADC_Channel_2;
break;
case PA_3:
channel = ADC_Channel_3;
break;
case PA_4:
channel = ADC_Channel_4;
break;
case PA_5:
channel = ADC_Channel_5;
break;
case PA_6:
channel = ADC_Channel_6;
break;
case PA_7:
channel = ADC_Channel_7;
break;
case PB_0:
channel = ADC_Channel_8;
break;
case PB_1:
channel = ADC_Channel_9;
break;
case PB_12:
channel = ADC_Channel_18;
break;
case PB_13:
channel = ADC_Channel_19;
break;
case PB_14:
channel = ADC_Channel_20;
break;
case PB_15:
channel = ADC_Channel_21;
break;
case PC_0:
channel = ADC_Channel_10;
break;
case PC_1:
channel = ADC_Channel_11;
break;
case PC_2:
channel = ADC_Channel_12;
break;
case PC_3:
channel = ADC_Channel_13;
break;
case PC_4:
channel = ADC_Channel_14;
break;
case PC_5:
channel = ADC_Channel_15;
break;
default:
return 0;
}
ADC_RegularChannelConfig(adc, channel, 1, ADC_SampleTime_4Cycles);
ADC_SoftwareStartConv(adc); // Start conversion
while (ADC_GetFlagStatus(adc, ADC_FLAG_EOC) == RESET); // Wait end of conversion
return (ADC_GetConversionValue(adc)); // Get conversion value
} }
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

@ -43,7 +43,7 @@ static const PinMap PinMap_DAC[] = {
void analogout_init(dac_t *obj, PinName pin) { void analogout_init(dac_t *obj, PinName pin) {
DAC_InitTypeDef DAC_InitStructure; DAC_InitTypeDef DAC_InitStructure;
// Get the peripheral name (DAC_1, ...) from the pin and assign it to the object // Get the peripheral name (DAC_1, ...) from the pin and assign it to the object
obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC); obj->dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
@ -65,7 +65,7 @@ void analogout_init(dac_t *obj, PinName pin) {
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
if (obj->channel == PA_4) { if (obj->channel == PA_4) {
DAC_Init(DAC_Channel_1, &DAC_InitStructure); DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_1, ENABLE); DAC_Cmd(DAC_Channel_1, ENABLE);
@ -74,7 +74,7 @@ void analogout_init(dac_t *obj, PinName pin) {
DAC_Init(DAC_Channel_2, &DAC_InitStructure); DAC_Init(DAC_Channel_2, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_2, ENABLE); DAC_Cmd(DAC_Channel_2, ENABLE);
} }
analogout_write_u16(obj, 0); analogout_write_u16(obj, 0);
} }
@ -112,10 +112,9 @@ void analogout_write(dac_t *obj, float value) {
void analogout_write_u16(dac_t *obj, uint16_t value) { void analogout_write_u16(dac_t *obj, uint16_t value) {
if (value > (uint16_t)RANGE_12BIT) { if (value > (uint16_t)RANGE_12BIT) {
dac_write(obj, (uint16_t)RANGE_12BIT); // Max value dac_write(obj, (uint16_t)RANGE_12BIT); // Max value
} } else {
else { dac_write(obj, value);
dac_write(obj, value);
} }
} }

View File

@ -33,7 +33,7 @@
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(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); pin_function(pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
@ -45,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);
@ -65,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(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)); pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF));
} } else { // PIN_INPUT
else { // PIN_INPUT
pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); pin_function(obj->pin, STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
} }
} }

View File

@ -29,7 +29,6 @@
*/ */
#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 "error.h" #include "error.h"
@ -53,30 +52,42 @@ 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 (EXTI_GetITStatus(pin) != RESET) if (EXTI_GetITStatus(pin) != RESET) {
{
EXTI_ClearITPendingBit(pin); EXTI_ClearITPendingBit(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 static void gpio_irq0(void) {
static void gpio_irq1(void) {handle_interrupt_in(1);} // EXTI line 1 handle_interrupt_in(0); // EXTI line 0
static void gpio_irq2(void) {handle_interrupt_in(2);} // EXTI line 2 }
static void gpio_irq3(void) {handle_interrupt_in(3);} // EXTI line 3 static void gpio_irq1(void) {
static void gpio_irq4(void) {handle_interrupt_in(4);} // EXTI line 4 handle_interrupt_in(1); // EXTI line 1
static void gpio_irq5(void) {handle_interrupt_in(5);} // EXTI lines 5 to 9 }
static void gpio_irq6(void) {handle_interrupt_in(6);} // EXTI lines 10 to 15 static void gpio_irq2(void) {
handle_interrupt_in(2); // EXTI line 2
}
static void gpio_irq3(void) {
handle_interrupt_in(3); // EXTI line 3
}
static void gpio_irq4(void) {
handle_interrupt_in(4); // EXTI line 4
}
static void gpio_irq5(void) {
handle_interrupt_in(5); // EXTI lines 5 to 9
}
static void gpio_irq6(void) {
handle_interrupt_in(6); // EXTI lines 10 to 15
}
extern uint32_t Set_GPIO_Clock(uint32_t port_idx); extern uint32_t Set_GPIO_Clock(uint32_t port_idx);
@ -146,18 +157,18 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
// Enable SYSCFG clock // Enable SYSCFG clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
// Connect EXTI line to pin // Connect EXTI line to pin
SYSCFG_EXTILineConfig(port_index, pin_index); SYSCFG_EXTILineConfig(port_index, pin_index);
// Configure EXTI line // Configure EXTI line
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); EXTI_Init(&EXTI_InitStructure);
// Enable and set EXTI interrupt to the lowest priority // Enable and set EXTI interrupt to the lowest priority
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = irq_n; NVIC_InitStructure.NVIC_IRQChannel = irq_n;
@ -165,7 +176,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); NVIC_Init(&NVIC_InitStructure);
NVIC_SetVector(irq_n, vector); NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n); NVIC_EnableIRQ(irq_n);
@ -176,9 +187,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;
} }
@ -189,47 +200,44 @@ void gpio_irq_free(gpio_irq_t *obj) {
// Disable EXTI line // Disable EXTI line
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
EXTI_StructInit(&EXTI_InitStructure); EXTI_StructInit(&EXTI_InitStructure);
EXTI_Init(&EXTI_InitStructure); EXTI_Init(&EXTI_InitStructure);
obj->event = EDGE_NONE; obj->event = EDGE_NONE;
} }
void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
uint32_t pin_index = channel_pin[obj->irq_index]; uint32_t pin_index = channel_pin[obj->irq_index];
EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index); EXTI_InitStructure.EXTI_Line = (uint32_t)(1 << pin_index);
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
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)) {
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
obj->event = EDGE_BOTH; obj->event = EDGE_BOTH;
} } else { // NONE or RISE
else { // NONE or RISE
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_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)) {
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
obj->event = EDGE_BOTH; obj->event = EDGE_BOTH;
} } else { // NONE or FALL
else { // NONE or FALL
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
obj->event = EDGE_FALL; obj->event = EDGE_FALL;
} }
} }
if (enable) { if (enable) {
EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_InitStructure.EXTI_LineCmd = ENABLE;
} } else {
else {
EXTI_InitStructure.EXTI_LineCmd = DISABLE; EXTI_InitStructure.EXTI_LineCmd = DISABLE;
} }
EXTI_Init(&EXTI_InitStructure); EXTI_Init(&EXTI_InitStructure);
} }

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

@ -36,8 +36,8 @@
#include "error.h" #include "error.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)
@ -55,19 +55,19 @@ static const PinMap PinMap_I2C_SCL[] = {
{NC, NC, 0} {NC, NC, 0}
}; };
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 pin mapping failed"); error("I2C pin mapping failed");
} }
// Enable I2C clock // Enable I2C clock
if (obj->i2c == I2C_1) { if (obj->i2c == I2C_1) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
} }
if (obj->i2c == I2C_2) { if (obj->i2c == I2C_2) {
@ -79,12 +79,12 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
pin_mode(scl, OpenDrain); pin_mode(scl, OpenDrain);
pinmap_pinout(sda, PinMap_I2C_SDA); pinmap_pinout(sda, PinMap_I2C_SDA);
pin_mode(sda, OpenDrain); pin_mode(sda, 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) {
@ -97,7 +97,7 @@ void i2c_frequency(i2c_t *obj, int hz) {
/* Warning: To use the I2C at 400 kHz (in fast mode), the PCLK1 frequency /* Warning: To use the I2C at 400 kHz (in fast mode), the PCLK1 frequency
(I2C peripheral input clock) must be a multiple of 10 MHz. (I2C peripheral input clock) must be a multiple of 10 MHz.
With the actual clock configuration, the max frequency is measured at 296 kHz */ With the actual clock configuration, the max frequency is measured at 296 kHz */
// I2C configuration // I2C configuration
I2C_DeInit(i2c); I2C_DeInit(i2c);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
@ -113,12 +113,12 @@ 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;
I2C_ClearFlag(i2c, I2C_FLAG_AF); // Clear Acknowledge failure flag I2C_ClearFlag(i2c, I2C_FLAG_AF); // Clear Acknowledge failure flag
// Generate the START condition // Generate the START condition
I2C_GenerateSTART(i2c, ENABLE); I2C_GenerateSTART(i2c, ENABLE);
// Wait the START condition has been correctly sent // Wait the START condition has been correctly sent
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
while (I2C_GetFlagStatus(i2c, I2C_FLAG_SB) == RESET) { while (I2C_GetFlagStatus(i2c, I2C_FLAG_SB) == RESET) {
@ -127,7 +127,7 @@ inline int i2c_start(i2c_t *obj) {
return 1; return 1;
} }
} }
return 0; return 0;
} }
@ -135,10 +135,10 @@ inline int i2c_stop(i2c_t *obj) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
int timeout; int timeout;
volatile int temp; volatile int temp;
if (I2C_GetFlagStatus(i2c, I2C_FLAG_MSL) == RESET) { if (I2C_GetFlagStatus(i2c, I2C_FLAG_MSL) == RESET) {
timeout = LONG_TIMEOUT; timeout = LONG_TIMEOUT;
// wait for STOP // wait for STOP
while (I2C_GetFlagStatus(i2c, I2C_FLAG_STOPF) == RESET) { while (I2C_GetFlagStatus(i2c, I2C_FLAG_STOPF) == RESET) {
timeout--; timeout--;
if (timeout == 0) { if (timeout == 0) {
@ -147,11 +147,10 @@ inline int i2c_stop(i2c_t *obj) {
} }
temp = i2c->SR1; temp = i2c->SR1;
I2C_Cmd(i2c, ENABLE); I2C_Cmd(i2c, ENABLE);
} } else {
else {
I2C_GenerateSTOP(i2c, ENABLE); I2C_GenerateSTOP(i2c, ENABLE);
} }
return 0; return 0;
} }
@ -160,13 +159,13 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
int timeout; int timeout;
int count; int count;
int value; int value;
if (length == 0) return 0; if (length == 0) return 0;
i2c_start(obj); i2c_start(obj);
// Send slave address for read // Send slave address for read
I2C_Send7bitAddress(i2c, address, I2C_Direction_Receiver); I2C_Send7bitAddress(i2c, address, I2C_Direction_Receiver);
// Wait address is acknowledged // Wait address is acknowledged
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
@ -176,13 +175,13 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
return 0; return 0;
} }
} }
// Read all bytes except last one // Read all bytes except last one
for (count = 0; count < (length - 1); count++) { for (count = 0; count < (length - 1); count++) {
value = i2c_byte_read(obj, 0); value = i2c_byte_read(obj, 0);
data[count] = (char)value; data[count] = (char)value;
} }
// If not repeated start, send stop. // If not repeated start, send stop.
// Warning: must be done BEFORE the data is read. // Warning: must be done BEFORE the data is read.
if (stop) { if (stop) {
@ -192,7 +191,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
// Read the last byte // Read the last byte
value = i2c_byte_read(obj, 1); value = i2c_byte_read(obj, 1);
data[count] = (char)value; data[count] = (char)value;
return length; return length;
} }
@ -205,7 +204,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
// Send slave address for write // Send slave address for write
I2C_Send7bitAddress(i2c, address, I2C_Direction_Transmitter); I2C_Send7bitAddress(i2c, address, I2C_Direction_Transmitter);
// Wait address is acknowledged // Wait address is acknowledged
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR) { while (I2C_CheckEvent(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR) {
@ -234,7 +233,7 @@ int i2c_byte_read(i2c_t *obj, int last) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint8_t data; uint8_t data;
int timeout; int timeout;
if (last) { if (last) {
// Don't acknowledge the last byte // Don't acknowledge the last byte
I2C_AcknowledgeConfig(i2c, DISABLE); I2C_AcknowledgeConfig(i2c, DISABLE);
@ -253,7 +252,7 @@ int i2c_byte_read(i2c_t *obj, int last) {
} }
data = I2C_ReceiveData(i2c); data = I2C_ReceiveData(i2c);
return (int)data; return (int)data;
} }
@ -266,24 +265,24 @@ int i2c_byte_write(i2c_t *obj, int data) {
// Wait until the byte is transmitted // Wait until the byte is transmitted
timeout = FLAG_TIMEOUT; timeout = FLAG_TIMEOUT;
while ((I2C_GetFlagStatus(i2c, I2C_FLAG_TXE) == RESET) && while ((I2C_GetFlagStatus(i2c, I2C_FLAG_TXE) == RESET) &&
(I2C_GetFlagStatus(i2c, I2C_FLAG_BTF) == RESET)) { (I2C_GetFlagStatus(i2c, I2C_FLAG_BTF) == RESET)) {
timeout--; timeout--;
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) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
} }
if (obj->i2c == I2C_2) { if (obj->i2c == I2C_2) {
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
} }
} }
@ -292,7 +291,7 @@ void i2c_reset(i2c_t *obj) {
void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c); I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
uint16_t tmpreg; uint16_t tmpreg;
// Get the old register value // Get the old register value
tmpreg = i2c->OAR1; tmpreg = i2c->OAR1;
// Reset address bits // Reset address bits
@ -314,28 +313,28 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver) #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
int i2c_slave_receive(i2c_t *obj) { int i2c_slave_receive(i2c_t *obj) {
return(0); return (0);
} }
int i2c_slave_read(i2c_t *obj, char *data, int length) { int i2c_slave_read(i2c_t *obj, char *data, int length) {
int count = 0; int count = 0;
// Read all bytes // Read all bytes
for (count = 0; count < length; count++) { for (count = 0; count < length; count++) {
data[count] = i2c_byte_read(obj, 0); data[count] = i2c_byte_read(obj, 0);
} }
return count; return count;
} }
int i2c_slave_write(i2c_t *obj, const char *data, int length) { int i2c_slave_write(i2c_t *obj, const char *data, int length) {
int count = 0; int count = 0;
// Write all bytes // Write all bytes
for (count = 0; count < length; count++) { for (count = 0; count < length; count++) {
i2c_byte_write(obj, data[count]); i2c_byte_write(obj, data[count]);
} }
return count; return count;
} }

View File

@ -25,8 +25,7 @@
* 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.
*/ */
#include "cmsis.h"
extern void SystemCoreClockUpdate(void);
// This function is called after RAM initialization and before main. // This function is called after RAM initialization and before main.
void mbed_sdk_init() { void mbed_sdk_init() {

View File

@ -48,7 +48,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 uint16_t *reg_in; __IO uint16_t *reg_in;
__IO uint16_t *reg_out; __IO uint16_t *reg_out;
}; };
@ -69,7 +69,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

@ -86,7 +86,7 @@ void pin_function(PinName pin, int data) {
if (afnum != 0xFF) { if (afnum != 0xFF) {
GPIO_PinAFConfig(gpio, (uint16_t)pin_index, afnum); GPIO_PinAFConfig(gpio, (uint16_t)pin_index, afnum);
} }
// Configure GPIO // Configure GPIO
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index); GPIO_InitStructure.GPIO_Pin = (uint16_t)(1 << pin_index);
@ -95,7 +95,7 @@ void pin_function(PinName pin, int data) {
GPIO_InitStructure.GPIO_OType = (GPIOOType_TypeDef)otype; GPIO_InitStructure.GPIO_OType = (GPIOOType_TypeDef)otype;
GPIO_InitStructure.GPIO_PuPd = (GPIOPuPd_TypeDef)pupd; GPIO_InitStructure.GPIO_PuPd = (GPIOPuPd_TypeDef)pupd;
GPIO_Init(gpio, &GPIO_InitStructure); 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)) {
@ -103,7 +103,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)) {
// //
//} //}
} }
/** /**
@ -124,5 +124,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

@ -28,18 +28,19 @@
******************************************************************************* *******************************************************************************
*/ */
#include "port_api.h" #include "port_api.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
#include "pinmap.h" #include "pinmap.h"
#include "gpio_api.h" #include "gpio_api.h"
#include "error.h" #include "error.h"
#if DEVICE_PORTIN || DEVICE_PORTOUT
extern uint32_t Set_GPIO_Clock(uint32_t port_idx); 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) {
@ -52,9 +53,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);
} }
@ -66,16 +67,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(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF)); pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_OUT, GPIO_OType_PP, GPIO_PuPd_NOPULL, 0xFF));
} } else { // PIN_INPUT
else { // PIN_INPUT
pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF)); pin_function(port_pin(obj->port, i), STM_PIN_DATA(GPIO_Mode_IN, 0, GPIO_PuPd_NOPULL, 0xFF));
} }
} }
} }
} }
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);
@ -90,8 +90,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,25 +29,27 @@
*/ */
#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"
// 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_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM5)}, // TIM5_CH1 // {PA_0, PWM_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM5)}, // TIM5_CH1
{PA_1, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH2 {PA_1, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH2
//{PA_1, PWM_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM5)}, // TIM5_CH1 // {PA_1, PWM_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM5)}, // TIM5_CH1
{PA_2, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH3 {PA_2, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH3
//{PA_2, PWM_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM5)}, // TIM5_CH3 // {PA_2, PWM_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM5)}, // TIM5_CH3
//{PA_2, PWM_9, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM9)}, // TIM9_CH1 // {PA_2, PWM_9, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM9)}, // TIM9_CH1
{PA_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH4 {PA_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH4
//{PA_3, PWM_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM5)}, // TIM5_CH4 // {PA_3, PWM_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM5)}, // TIM5_CH4
//{PA_3, PWM_9, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM9)}, // TIM9_CH2 // {PA_3, PWM_9, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM9)}, // TIM9_CH2
{PA_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH1 {PA_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH1
//{PA_6, PWM_10, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM10)}, // TIM10_CH1 // {PA_6, PWM_10, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM10)}, // TIM10_CH1
{PA_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH2 {PA_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH2
//{PA_7, PWM_11, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM11)}, // TIM11_CH1 // {PA_7, PWM_11, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM11)}, // TIM11_CH1
{PB_0, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH3 {PB_0, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH3
{PB_1, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH4 {PB_1, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH4
{PB_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH2 {PB_3, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH2
@ -56,30 +58,30 @@ static const PinMap PinMap_PWM[] = {
{PB_6, PWM_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM4)}, // TIM4_CH1 {PB_6, PWM_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM4)}, // TIM4_CH1
{PB_7, PWM_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM4)}, // TIM4_CH2 {PB_7, PWM_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM4)}, // TIM4_CH2
{PB_8, PWM_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM4)}, // TIM4_CH3 {PB_8, PWM_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM4)}, // TIM4_CH3
//{PB_8, PWM_10, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM10)}, // TIM10_CH1 // {PB_8, PWM_10, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM10)}, // TIM10_CH1
{PB_9, PWM_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM4)}, // TIM4_CH4 {PB_9, PWM_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM4)}, // TIM4_CH4
//{PB_9, PWM_11, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM11)}, // TIM11_CH1 // {PB_9, PWM_11, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM11)}, // TIM11_CH1
{PB_10, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH3 {PB_10, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH3
{PB_11, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH4 {PB_11, PWM_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM2)}, // TIM2_CH4
{PB_12, PWM_10, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM10)}, // TIM10_CH1 {PB_12, PWM_10, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM10)}, // TIM10_CH1
{PB_13, PWM_9, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM9)}, // TIM9_CH1 {PB_13, PWM_9, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM9)}, // TIM9_CH1
{PB_14, PWM_9, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM9)}, // TIM9_CH2 {PB_14, PWM_9, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM9)}, // TIM9_CH2
{PB_15, PWM_11, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM11)}, // TIM11_CH1 {PB_15, PWM_11, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM11)}, // TIM11_CH1
{PC_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH1 {PC_6, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH1
{PC_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH2 {PC_7, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH2
{PC_8, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH3 {PC_8, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH3
{PC_9, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH4 {PC_9, PWM_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_TIM3)}, // TIM3_CH4
{NC, NC, 0} {NC, NC, 0}
}; };
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 pinout mapping failed"); error("PWM pinout mapping failed");
} }
// Enable TIM clock // Enable TIM clock
if (obj->pwm == PWM_2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); if (obj->pwm == PWM_2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
if (obj->pwm == PWM_3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); if (obj->pwm == PWM_3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
@ -88,14 +90,14 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
if (obj->pwm == PWM_9) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE); if (obj->pwm == PWM_9) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9, ENABLE);
if (obj->pwm == PWM_10) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE); if (obj->pwm == PWM_10) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10, ENABLE);
if (obj->pwm == PWM_11) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, ENABLE); if (obj->pwm == PWM_11) RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, 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
} }
@ -113,9 +115,9 @@ void pwmout_write(pwmout_t* obj, float value) {
} else if (value > 1.0) { } else if (value > 1.0) {
value = 1.0; value = 1.0;
} }
obj->pulse = (uint32_t)((float)obj->period * value); obj->pulse = (uint32_t)((float)obj->period * value);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = obj->pulse; TIM_OCInitStructure.TIM_Pulse = obj->pulse;
@ -124,15 +126,15 @@ void pwmout_write(pwmout_t* obj, float value) {
// Configure the channels // Configure the channels
switch (obj->pin) { switch (obj->pin) {
// Channels 1 // Channels 1
//case PA_0: //case PA_0:
//case PA_1: //case PA_1:
//case PA_2: //case PA_2:
case PA_6: case PA_6:
//case PA_7: //case PA_7:
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 PB_12: case PB_12:
case PB_13: case PB_13:
case PB_15: case PB_15:
@ -142,7 +144,7 @@ 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 PB_3: case PB_3:
case PB_5: case PB_5:
@ -169,7 +171,7 @@ void pwmout_write(pwmout_t* obj, float value) {
case PC_9: case PC_9:
TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(tim, TIM_OCPreload_Enable);
TIM_OC4Init(tim, &TIM_OCInitStructure); TIM_OC4Init(tim, &TIM_OCInitStructure);
break; break;
default: default:
return; return;
} }
@ -196,10 +198,10 @@ void pwmout_period_us(pwmout_t* obj, int us) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
float dc = pwmout_read(obj); float dc = pwmout_read(obj);
TIM_Cmd(tim, DISABLE); TIM_Cmd(tim, DISABLE);
obj->period = us; obj->period = us;
TIM_TimeBaseStructure.TIM_Period = obj->period - 1; TIM_TimeBaseStructure.TIM_Period = obj->period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0;
@ -208,8 +210,8 @@ 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);
TIM_ARRPreloadConfig(tim, ENABLE); TIM_ARRPreloadConfig(tim, ENABLE);
TIM_Cmd(tim, ENABLE); TIM_Cmd(tim, ENABLE);
} }
@ -225,3 +227,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

@ -29,36 +29,63 @@
*/ */
#include "rtc_api.h" #include "rtc_api.h"
#if DEVICE_RTC
#include "wait_api.h"
#define LSE_STARTUP_TIMEOUT ((uint16_t)400) // delay in ms
static int rtc_inited = 0; static int rtc_inited = 0;
void rtc_init(void) { void rtc_init(void) {
uint32_t StartUpCounter = 0;
uint32_t LSEStatus = 0;
uint32_t rtc_freq = 0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Enable PWR clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); // Enable PWR clock
PWR_RTCAccessCmd(ENABLE); // Enable access to RTC PWR_RTCAccessCmd(ENABLE); // Enable access to Backup domain
// Note: the LSI is used as RTC source clock // Reset RTC and Backup registers
// The RTC Clock may vary due to LSI frequency dispersion. RCC_RTCResetCmd(ENABLE);
RCC_RTCResetCmd(DISABLE);
RCC_LSICmd(ENABLE); // Enable LSI
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select LSI as RTC Clock Source
RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock
RTC_WaitForSynchro(); // Wait for RTC registers synchronization
uint32_t lsi_freq = 40000; // [TODO] To be measured precisely using a timer input capture // Enable LSE clock
RCC_LSEConfig(RCC_LSE_ON);
// Wait till LSE is ready
do {
LSEStatus = RCC_GetFlagStatus(RCC_FLAG_LSERDY);
wait_ms(1);
StartUpCounter++;
} while ((LSEStatus == 0) && (StartUpCounter <= LSE_STARTUP_TIMEOUT));
if (StartUpCounter > LSE_STARTUP_TIMEOUT) {
// The LSE has not started, use LSI instead.
// The RTC Clock may vary due to LSI frequency dispersion.
RCC_LSEConfig(RCC_LSE_OFF);
RCC_LSICmd(ENABLE); // Enable LSI
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} // Wait until ready
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); // Select the RTC Clock Source
rtc_freq = 40000; // [TODO] To be measured precisely using a timer input capture
} else {
// The LSE has correctly started
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); // Select the RTC Clock Source
rtc_freq = LSE_VALUE;
}
RTC_InitTypeDef RTC_InitStructure; RTC_InitTypeDef RTC_InitStructure;
RTC_InitStructure.RTC_AsynchPrediv = 127; RTC_InitStructure.RTC_AsynchPrediv = 127;
RTC_InitStructure.RTC_SynchPrediv = (lsi_freq / 128) - 1; RTC_InitStructure.RTC_SynchPrediv = (rtc_freq / 128) - 1;
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24; RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStructure); RTC_Init(&RTC_InitStructure);
PWR_RTCAccessCmd(DISABLE); // Disable access to RTC RCC_RTCCLKCmd(ENABLE); // Enable RTC Clock
RTC_WaitForSynchro(); // Wait for RTC registers synchronization
PWR_RTCAccessCmd(DISABLE); // Disable access to Backup domain
rtc_inited = 1; rtc_inited = 1;
} }
@ -92,11 +119,11 @@ time_t rtc_read(void) {
RTC_DateTypeDef dateStruct; RTC_DateTypeDef dateStruct;
RTC_TimeTypeDef timeStruct; RTC_TimeTypeDef timeStruct;
struct tm timeinfo; struct tm timeinfo;
// Read actual date and time // Read actual date and time
RTC_GetTime(RTC_Format_BIN, &timeStruct); RTC_GetTime(RTC_Format_BIN, &timeStruct);
RTC_GetDate(RTC_Format_BIN, &dateStruct); RTC_GetDate(RTC_Format_BIN, &dateStruct);
// Setup a tm structure based on the RTC // Setup a tm structure based on the RTC
timeinfo.tm_wday = dateStruct.RTC_WeekDay; timeinfo.tm_wday = dateStruct.RTC_WeekDay;
timeinfo.tm_mon = dateStruct.RTC_Month - 1; timeinfo.tm_mon = dateStruct.RTC_Month - 1;
@ -105,11 +132,11 @@ time_t rtc_read(void) {
timeinfo.tm_hour = timeStruct.RTC_Hours; timeinfo.tm_hour = timeStruct.RTC_Hours;
timeinfo.tm_min = timeStruct.RTC_Minutes; timeinfo.tm_min = timeStruct.RTC_Minutes;
timeinfo.tm_sec = timeStruct.RTC_Seconds; timeinfo.tm_sec = timeStruct.RTC_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) {
@ -118,7 +145,7 @@ void rtc_write(time_t t) {
// 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.RTC_WeekDay = timeinfo->tm_wday; dateStruct.RTC_WeekDay = timeinfo->tm_wday;
dateStruct.RTC_Month = timeinfo->tm_mon + 1; dateStruct.RTC_Month = timeinfo->tm_mon + 1;
@ -128,10 +155,12 @@ void rtc_write(time_t t) {
timeStruct.RTC_Minutes = timeinfo->tm_min; timeStruct.RTC_Minutes = timeinfo->tm_min;
timeStruct.RTC_Seconds = timeinfo->tm_sec; timeStruct.RTC_Seconds = timeinfo->tm_sec;
timeStruct.RTC_H12 = RTC_HourFormat_24; timeStruct.RTC_H12 = RTC_HourFormat_24;
// Change the RTC current date/time // Change the RTC current date/time
PWR_RTCAccessCmd(ENABLE); // Enable access to RTC PWR_RTCAccessCmd(ENABLE); // Enable access to Backup domain
RTC_SetDate(RTC_Format_BIN, &dateStruct); RTC_SetDate(RTC_Format_BIN, &dateStruct);
RTC_SetTime(RTC_Format_BIN, &timeStruct); RTC_SetTime(RTC_Format_BIN, &timeStruct);
PWR_RTCAccessCmd(DISABLE); // Disable access to RTC PWR_RTCAccessCmd(DISABLE); // Disable access to Backup domain
} }
#endif

View File

@ -28,6 +28,9 @@
******************************************************************************* *******************************************************************************
*/ */
#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"
@ -38,7 +41,7 @@ static const PinMap PinMap_UART_TX[] = {
{PA_9, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART1)}, {PA_9, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART1)},
{PB_6, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART1)}, {PB_6, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART1)},
{PB_10, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART3)}, {PB_10, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART3)},
//{PC_10, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART3)}, // {PC_10, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART3)},
{PC_10, UART_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_UART4)}, {PC_10, UART_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_UART4)},
{PC_12, UART_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_UART5)}, {PC_12, UART_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_UART5)},
{NC, NC, 0} {NC, NC, 0}
@ -49,7 +52,7 @@ static const PinMap PinMap_UART_RX[] = {
{PA_10, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART1)}, {PA_10, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART1)},
{PB_7, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART1)}, {PB_7, UART_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART1)},
{PB_11, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART3)}, {PB_11, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART3)},
//{PC_11, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART3)}, // {PC_11, UART_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_USART3)},
{PC_11, UART_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_UART4)}, {PC_11, UART_4, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_UART4)},
{PD_2, UART_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_UART5)}, {PD_2, UART_5, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_UART5)},
{NC, NC, 0} {NC, NC, 0}
@ -67,7 +70,7 @@ serial_t stdio_uart;
static void init_usart(serial_t *obj) { static void init_usart(serial_t *obj) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); USART_TypeDef *usart = (USART_TypeDef *)(obj->uart);
USART_InitTypeDef USART_InitStructure; USART_InitTypeDef USART_InitStructure;
USART_Cmd(usart, DISABLE); USART_Cmd(usart, DISABLE);
USART_InitStructure.USART_BaudRate = obj->baudrate; USART_InitStructure.USART_BaudRate = obj->baudrate;
@ -77,15 +80,15 @@ static void init_usart(serial_t *obj) {
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(usart, &USART_InitStructure); USART_Init(usart, &USART_InitStructure);
USART_Cmd(usart, ENABLE); USART_Cmd(usart, ENABLE);
} }
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);
@ -95,19 +98,19 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
// Enable USART clock // Enable USART clock
if (obj->uart == UART_1) { if (obj->uart == UART_1) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
} }
if (obj->uart == UART_2) { if (obj->uart == UART_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
} }
if (obj->uart == UART_3) { if (obj->uart == UART_3) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
} }
if (obj->uart == UART_4) { if (obj->uart == UART_4) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
} }
if (obj->uart == UART_5) { if (obj->uart == UART_5) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
} }
// Configure the UART pins // Configure the UART pins
@ -120,7 +123,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
obj->baudrate = 9600; obj->baudrate = 9600;
obj->databits = USART_WordLength_8b; obj->databits = USART_WordLength_8b;
obj->stopbits = USART_StopBits_1; obj->stopbits = USART_StopBits_1;
obj->parity = USART_Parity_No; obj->parity = USART_Parity_No;
init_usart(obj); init_usart(obj);
@ -130,12 +133,12 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
if (obj->uart == UART_3) obj->index = 2; if (obj->uart == UART_3) obj->index = 2;
if (obj->uart == UART_4) obj->index = 3; if (obj->uart == UART_4) obj->index = 3;
if (obj->uart == UART_5) obj->index = 4; if (obj->uart == UART_5) obj->index = 4;
// 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) {
@ -150,29 +153,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 = USART_WordLength_8b; obj->databits = USART_WordLength_8b;
} } else {
else {
obj->databits = USART_WordLength_9b; obj->databits = USART_WordLength_9b;
} }
switch (parity) { switch (parity) {
case ParityOdd: case ParityOdd:
case ParityForced0: case ParityForced0:
obj->parity = USART_Parity_Odd; obj->parity = USART_Parity_Odd;
break; break;
case ParityEven: case ParityEven:
case ParityForced1: case ParityForced1:
obj->parity = USART_Parity_Even; obj->parity = USART_Parity_Even;
break; break;
default: // ParityNone default: // ParityNone
obj->parity = USART_Parity_No; obj->parity = USART_Parity_No;
break; break;
} }
if (stop_bits == 2) { if (stop_bits == 2) {
obj->stopbits = USART_StopBits_2; obj->stopbits = USART_StopBits_2;
} } else {
else {
obj->stopbits = USART_StopBits_1; obj->stopbits = USART_StopBits_1;
} }
@ -197,11 +198,21 @@ static void uart_irq(USART_TypeDef* usart, int id) {
} }
} }
static void uart1_irq(void) {uart_irq((USART_TypeDef*)UART_1, 0);} static void uart1_irq(void) {
static void uart2_irq(void) {uart_irq((USART_TypeDef*)UART_2, 1);} uart_irq((USART_TypeDef*)UART_1, 0);
static void uart3_irq(void) {uart_irq((USART_TypeDef*)UART_3, 2);} }
static void uart4_irq(void) {uart_irq((USART_TypeDef*)UART_4, 3);} static void uart2_irq(void) {
static void uart5_irq(void) {uart_irq((USART_TypeDef*)UART_5, 4);} uart_irq((USART_TypeDef*)UART_2, 1);
}
static void uart3_irq(void) {
uart_irq((USART_TypeDef*)UART_3, 2);
}
static void uart4_irq(void) {
uart_irq((USART_TypeDef*)UART_4, 3);
}
static void uart5_irq(void) {
uart_irq((USART_TypeDef*)UART_5, 4);
}
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;
@ -214,60 +225,58 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
USART_TypeDef *usart = (USART_TypeDef *)(obj->uart); USART_TypeDef *usart = (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_3) { if (obj->uart == UART_3) {
irq_n = USART3_IRQn; irq_n = USART3_IRQn;
vector = (uint32_t)&uart3_irq; vector = (uint32_t)&uart3_irq;
} }
if (obj->uart == UART_4) { if (obj->uart == UART_4) {
irq_n = UART4_IRQn; irq_n = UART4_IRQn;
vector = (uint32_t)&uart4_irq; vector = (uint32_t)&uart4_irq;
} }
if (obj->uart == UART_5) { if (obj->uart == UART_5) {
irq_n = UART5_IRQn; irq_n = UART5_IRQn;
vector = (uint32_t)&uart5_irq; vector = (uint32_t)&uart5_irq;
} }
if (enable) { if (enable) {
if (irq == RxIrq) { if (irq == RxIrq) {
USART_ITConfig(usart, USART_IT_RXNE, ENABLE); USART_ITConfig(usart, USART_IT_RXNE, ENABLE);
} } else { // TxIrq
else { // TxIrq
USART_ITConfig(usart, USART_IT_TC, ENABLE); USART_ITConfig(usart, USART_IT_TC, ENABLE);
} }
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) {
USART_ITConfig(usart, USART_IT_RXNE, DISABLE); USART_ITConfig(usart, USART_IT_RXNE, DISABLE);
// Check if TxIrq is disabled too // Check if TxIrq is disabled too
if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1; if ((usart->CR1 & USART_CR1_TXEIE) == 0) all_disabled = 1;
} } else { // TxIrq
else { // TxIrq
USART_ITConfig(usart, USART_IT_TXE, DISABLE); USART_ITConfig(usart, USART_IT_TXE, DISABLE);
// Check if RxIrq is disabled too // Check if RxIrq is disabled too
if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1; if ((usart->CR1 & USART_CR1_RXNEIE) == 0) all_disabled = 1;
} }
if (all_disabled) NVIC_DisableIRQ(irq_n); if (all_disabled) NVIC_DisableIRQ(irq_n);
} }
} }
/****************************************************************************** /******************************************************************************
@ -319,3 +328,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,33 +28,33 @@
******************************************************************************* *******************************************************************************
*/ */
#include "sleep_api.h" #include "sleep_api.h"
#if DEVICE_SLEEP
#include "cmsis.h" #include "cmsis.h"
// This function is in the system_stm32l1xx.c file
extern void SetSysClock(void);
// MCU SLEEP mode // MCU SLEEP mode
void sleep(void) void sleep(void) {
{
// Enable PWR clock // Enable PWR clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
// Request to enter SLEEP mode with regulator ON // Request to enter SLEEP mode with regulator ON
PWR_EnterSleepMode(PWR_Regulator_ON, PWR_SLEEPEntry_WFI); PWR_EnterSleepMode(PWR_Regulator_ON, PWR_SLEEPEntry_WFI);
} }
// MCU STOP mode (Regulator in LP mode, LSI, HSI and HSE OFF) // MCU STOP mode (Regulator in LP mode, LSI, HSI and HSE OFF)
void deepsleep(void) void deepsleep(void) {
{
// Enable PWR clock // Enable PWR clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
// Enable Ultra low power mode // Enable Ultra low power mode
PWR_UltraLowPowerCmd(ENABLE); PWR_UltraLowPowerCmd(ENABLE);
// Enter Stop Mode // Enter Stop Mode
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
// After wake-up from STOP reconfigure the PLL // After wake-up from STOP reconfigure the PLL
SetSysClock(); SetSysClock();
} }
#endif

View File

@ -37,29 +37,29 @@
#include "error.h" #include "error.h"
static const PinMap PinMap_SPI_MOSI[] = { static const PinMap PinMap_SPI_MOSI[] = {
{PA_7, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PA_7, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
{PA_12, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PA_12, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
{PB_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PB_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
//{PB_5, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)}, // {PB_5, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)},
{PB_15, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI2)}, {PB_15, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI2)},
{PC_12, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)}, {PC_12, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)},
{NC, NC, 0} {NC, NC, 0}
}; };
static const PinMap PinMap_SPI_MISO[] = { static const PinMap PinMap_SPI_MISO[] = {
{PA_6, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PA_6, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
{PA_11, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PA_11, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
{PB_4, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PB_4, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
//{PB_4, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)}, // {PB_4, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)},
{PB_14, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI2)}, {PB_14, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI2)},
{PC_11, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)}, {PC_11, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)},
{NC, NC, 0} {NC, NC, 0}
}; };
static const PinMap PinMap_SPI_SCLK[] = { static const PinMap PinMap_SPI_SCLK[] = {
{PA_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PA_5, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
{PB_3, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PB_3, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
//{PB_3, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)}, // {PB_3, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)},
{PB_13, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI2)}, {PB_13, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI2)},
{PC_10, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)}, {PC_10, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)},
{NC, NC, 0} {NC, NC, 0}
@ -67,9 +67,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(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PA_4, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
//{PA_4, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)}, // {PA_4, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)},
{PA_15, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)}, {PA_15, SPI_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI1)},
//{PA_15, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)}, // {PA_15, SPI_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI3)},
{PB_12, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI2)}, {PB_12, SPI_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SPI2)},
{NC, NC, 0} {NC, NC, 0}
}; };
@ -81,11 +81,11 @@ static void init_spi(spi_t *obj) {
SPI_Cmd(spi, DISABLE); SPI_Cmd(spi, DISABLE);
SPI_InitStructure.SPI_Mode = obj->mode; SPI_InitStructure.SPI_Mode = obj->mode;
SPI_InitStructure.SPI_NSS = obj->nss; SPI_InitStructure.SPI_NSS = obj->nss;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_DataSize = obj->bits; SPI_InitStructure.SPI_DataSize = obj->bits;
SPI_InitStructure.SPI_CPOL = obj->cpol; SPI_InitStructure.SPI_CPOL = obj->cpol;
SPI_InitStructure.SPI_CPHA = obj->cpha; SPI_InitStructure.SPI_CPHA = obj->cpha;
SPI_InitStructure.SPI_BaudRatePrescaler = obj->br_presc; SPI_InitStructure.SPI_BaudRatePrescaler = obj->br_presc;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_InitStructure.SPI_CRCPolynomial = 7;
@ -100,43 +100,42 @@ 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 pinout mapping failed"); error("SPI pinout mapping failed");
} }
// Enable SPI clock // Enable SPI clock
if (obj->spi == SPI_1) { if (obj->spi == SPI_1) {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
} }
if (obj->spi == SPI_2) { if (obj->spi == SPI_2) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
} }
if (obj->spi == SPI_3) { if (obj->spi == SPI_3) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, 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_8b; obj->bits = SPI_DataSize_8b;
obj->cpol = SPI_CPOL_Low; obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_1Edge; obj->cpha = SPI_CPHA_1Edge;
obj->br_presc = SPI_BaudRatePrescaler_256; obj->br_presc = SPI_BaudRatePrescaler_256;
if (ssel == NC) { // Master if (ssel == NC) { // Master
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_Soft; obj->nss = SPI_NSS_Soft;
@ -150,43 +149,41 @@ void spi_free(spi_t *obj) {
SPI_I2S_DeInit(spi); SPI_I2S_DeInit(spi);
} }
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_8b; obj->bits = SPI_DataSize_8b;
} } else {
else {
obj->bits = SPI_DataSize_16b; obj->bits = SPI_DataSize_16b;
} }
switch (mode) { switch (mode) {
case 0: case 0:
obj->cpol = SPI_CPOL_Low; obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_1Edge; obj->cpha = SPI_CPHA_1Edge;
break; break;
case 1: case 1:
obj->cpol = SPI_CPOL_Low; obj->cpol = SPI_CPOL_Low;
obj->cpha = SPI_CPHA_2Edge; obj->cpha = SPI_CPHA_2Edge;
break; break;
case 2: case 2:
obj->cpol = SPI_CPOL_High; obj->cpol = SPI_CPOL_High;
obj->cpha = SPI_CPHA_1Edge; obj->cpha = SPI_CPHA_1Edge;
break; break;
default: default:
obj->cpol = SPI_CPOL_High; obj->cpol = SPI_CPOL_High;
obj->cpha = SPI_CPHA_2Edge; obj->cpha = SPI_CPHA_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; obj->nss = SPI_NSS_Hard;
} }
init_spi(obj); init_spi(obj);
} }
@ -195,54 +192,39 @@ void spi_frequency(spi_t *obj, int hz) {
if (SystemCoreClock == 32000000) { // HSI if (SystemCoreClock == 32000000) { // HSI
if (hz < 250000) { if (hz < 250000) {
obj->br_presc = SPI_BaudRatePrescaler_256; // 125 kHz obj->br_presc = SPI_BaudRatePrescaler_256; // 125 kHz
} } else if ((hz >= 250000) && (hz < 500000)) {
else if ((hz >= 250000) && (hz < 500000)) {
obj->br_presc = SPI_BaudRatePrescaler_128; // 250 kHz obj->br_presc = SPI_BaudRatePrescaler_128; // 250 kHz
} } else if ((hz >= 500000) && (hz < 1000000)) {
else if ((hz >= 500000) && (hz < 1000000)) {
obj->br_presc = SPI_BaudRatePrescaler_64; // 500 kHz obj->br_presc = SPI_BaudRatePrescaler_64; // 500 kHz
} } else if ((hz >= 1000000) && (hz < 2000000)) {
else if ((hz >= 1000000) && (hz < 2000000)) {
obj->br_presc = SPI_BaudRatePrescaler_32; // 1 MHz obj->br_presc = SPI_BaudRatePrescaler_32; // 1 MHz
} } else if ((hz >= 2000000) && (hz < 4000000)) {
else if ((hz >= 2000000) && (hz < 4000000)) {
obj->br_presc = SPI_BaudRatePrescaler_16; // 2 MHz obj->br_presc = SPI_BaudRatePrescaler_16; // 2 MHz
} } else if ((hz >= 4000000) && (hz < 8000000)) {
else if ((hz >= 4000000) && (hz < 8000000)) {
obj->br_presc = SPI_BaudRatePrescaler_8; // 4 MHz obj->br_presc = SPI_BaudRatePrescaler_8; // 4 MHz
} } else if ((hz >= 8000000) && (hz < 16000000)) {
else if ((hz >= 8000000) && (hz < 16000000)) {
obj->br_presc = SPI_BaudRatePrescaler_4; // 8 MHz obj->br_presc = SPI_BaudRatePrescaler_4; // 8 MHz
} } else { // >= 16000000
else { // >= 16000000
obj->br_presc = SPI_BaudRatePrescaler_2; // 16 MHz obj->br_presc = SPI_BaudRatePrescaler_2; // 16 MHz
} }
} } else { // 24 MHz - HSE
else { // 24 MHz - HSE
if (hz < 180000) { if (hz < 180000) {
obj->br_presc = SPI_BaudRatePrescaler_256; // 94 kHz obj->br_presc = SPI_BaudRatePrescaler_256; // 94 kHz
} } else if ((hz >= 180000) && (hz < 350000)) {
else if ((hz >= 180000) && (hz < 350000)) {
obj->br_presc = SPI_BaudRatePrescaler_128; // 188 kHz obj->br_presc = SPI_BaudRatePrescaler_128; // 188 kHz
} } else if ((hz >= 350000) && (hz < 750000)) {
else if ((hz >= 350000) && (hz < 750000)) {
obj->br_presc = SPI_BaudRatePrescaler_64; // 375 kHz obj->br_presc = SPI_BaudRatePrescaler_64; // 375 kHz
} } else if ((hz >= 750000) && (hz < 1000000)) {
else if ((hz >= 750000) && (hz < 1000000)) {
obj->br_presc = SPI_BaudRatePrescaler_32; // 750 kHz obj->br_presc = SPI_BaudRatePrescaler_32; // 750 kHz
} } else if ((hz >= 1000000) && (hz < 3000000)) {
else if ((hz >= 1000000) && (hz < 3000000)) {
obj->br_presc = SPI_BaudRatePrescaler_16; // 1.5 MHz obj->br_presc = SPI_BaudRatePrescaler_16; // 1.5 MHz
} } else if ((hz >= 3000000) && (hz < 6000000)) {
else if ((hz >= 3000000) && (hz < 6000000)) {
obj->br_presc = SPI_BaudRatePrescaler_8; // 3 MHz obj->br_presc = SPI_BaudRatePrescaler_8; // 3 MHz
} } else if ((hz >= 6000000) && (hz < 12000000)) {
else if ((hz >= 6000000) && (hz < 12000000)) {
obj->br_presc = SPI_BaudRatePrescaler_4; // 6 MHz obj->br_presc = SPI_BaudRatePrescaler_4; // 6 MHz
} } else { // >= 12000000
else { // >= 12000000
obj->br_presc = SPI_BaudRatePrescaler_2; // 12 MHz obj->br_presc = SPI_BaudRatePrescaler_2; // 12 MHz
} }
} }
init_spi(obj); init_spi(obj);
} }
@ -252,7 +234,7 @@ static inline int ssp_readable(spi_t *obj) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
// Check if data is received // Check if data is received
status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_FLAG_RXNE) != RESET) ? 1 : 0); status = ((SPI_I2S_GetFlagStatus(spi, SPI_I2S_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) {
@ -264,13 +246,13 @@ static inline int ssp_writeable(spi_t *obj) {
} }
static inline void ssp_write(spi_t *obj, int value) { static inline void ssp_write(spi_t *obj, int value) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_writeable(obj)); while (!ssp_writeable(obj));
SPI_I2S_SendData(spi, (uint16_t)value); SPI_I2S_SendData(spi, (uint16_t)value);
} }
static inline int ssp_read(spi_t *obj) { static inline int ssp_read(spi_t *obj) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_readable(obj)); while (!ssp_readable(obj));
return (int)SPI_I2S_ReceiveData(spi); return (int)SPI_I2S_ReceiveData(spi);
} }
@ -297,8 +279,8 @@ int spi_slave_read(spi_t *obj) {
} }
void spi_slave_write(spi_t *obj, int value) { void spi_slave_write(spi_t *obj, int value) {
SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi); SPI_TypeDef *spi = (SPI_TypeDef *)(obj->spi);
while (!ssp_writeable(obj)); while (!ssp_writeable(obj));
SPI_I2S_SendData(spi, (uint16_t)value); SPI_I2S_SendData(spi, (uint16_t)value);
} }

View File

@ -38,13 +38,13 @@ static int us_ticker_inited = 0;
void us_ticker_init(void) { void us_ticker_init(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
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
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF;
@ -52,10 +52,10 @@ void us_ticker_init(void) {
TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM_MST, &TIM_TimeBaseStructure); TIM_TimeBaseInit(TIM_MST, &TIM_TimeBaseStructure);
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
TIM_Cmd(TIM_MST, ENABLE); TIM_Cmd(TIM_MST, ENABLE);
} }