stm32_common: add delay when turn on peripheral clock
Implements workaround 1 (use __DSB()) proposed in the stm32 errata It was possible to lose data when you configure a peripheral right after enabling its clock
This commit is contained in:
parent
79043d2518
commit
2b37d369a0
@ -21,6 +21,9 @@
|
||||
#include "periph_conf.h"
|
||||
#include "periph_cpu_common.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
uint32_t periph_apb_clk(uint8_t bus)
|
||||
{
|
||||
if (bus == APB1) {
|
||||
@ -31,20 +34,66 @@ uint32_t periph_apb_clk(uint8_t bus)
|
||||
}
|
||||
}
|
||||
|
||||
void periph_clk_en(uint8_t bus, uint32_t mask)
|
||||
void periph_clk_en(bus_t bus, uint32_t mask)
|
||||
{
|
||||
if (bus == APB1) {
|
||||
RCC->APB1ENR |= mask;
|
||||
} else {
|
||||
RCC->APB2ENR |= mask;
|
||||
switch (bus) {
|
||||
case APB1:
|
||||
RCC->APB1ENR |= mask;
|
||||
break;
|
||||
case APB2:
|
||||
RCC->APB2ENR |= mask;
|
||||
break;
|
||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) || defined(CPU_FAM_STM32F1) \
|
||||
|| defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
case AHB:
|
||||
RCC->AHBENR |= mask;
|
||||
break;
|
||||
#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4)
|
||||
case AHB1:
|
||||
RCC->AHB1ENR |= mask;
|
||||
break;
|
||||
case AHB2:
|
||||
RCC->AHB2ENR |= mask;
|
||||
break;
|
||||
case AHB3:
|
||||
RCC->AHB3ENR |= mask;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DEBUG("unsupported bus %d\n", (int)bus);
|
||||
break;
|
||||
}
|
||||
/* stm32xx-errata: Delay after a RCC peripheral clock enable */
|
||||
__DSB();
|
||||
}
|
||||
|
||||
void periph_clk_dis(uint8_t bus, uint32_t mask)
|
||||
void periph_clk_dis(bus_t bus, uint32_t mask)
|
||||
{
|
||||
if (bus == APB1) {
|
||||
RCC->APB1ENR &= ~(mask);
|
||||
} else {
|
||||
RCC->APB2ENR &= ~(mask);
|
||||
switch (bus) {
|
||||
case APB1:
|
||||
RCC->APB1ENR &= ~(mask);
|
||||
break;
|
||||
case APB2:
|
||||
RCC->APB2ENR &= ~(mask);
|
||||
break;
|
||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) || defined(CPU_FAM_STM32F1) \
|
||||
|| defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
case AHB:
|
||||
RCC->AHBENR &= ~(mask);
|
||||
break;
|
||||
#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4)
|
||||
case AHB1:
|
||||
RCC->AHB1ENR &= ~(mask);
|
||||
break;
|
||||
case AHB2:
|
||||
RCC->AHB2ENR &= ~(mask);
|
||||
break;
|
||||
case AHB3:
|
||||
RCC->AHB3ENR &= ~(mask);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
DEBUG("unsupported bus %d\n", (int)bus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,10 +47,20 @@ extern "C" {
|
||||
/**
|
||||
* @brief Available peripheral buses
|
||||
*/
|
||||
enum {
|
||||
typedef enum {
|
||||
APB1, /**< APB1 bus */
|
||||
APB2 /**< APB2 bus */
|
||||
};
|
||||
APB2, /**< APB2 bus */
|
||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) || defined(CPU_FAM_STM32F1)\
|
||||
|| defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3)
|
||||
AHB, /**< AHB bus */
|
||||
#elif defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4)
|
||||
AHB1, /**< AHB1 bus */
|
||||
AHB2, /**< AHB2 bus */
|
||||
AHB3 /**< AHB3 bus */
|
||||
#else
|
||||
#warning "unsupported stm32XX family"
|
||||
#endif
|
||||
} bus_t;
|
||||
|
||||
/**
|
||||
* @brief Overwrite the default gpio_t type definition
|
||||
@ -132,7 +142,7 @@ uint32_t periph_apb_clk(uint8_t bus);
|
||||
* @param[in] bus bus the peripheral is connected to
|
||||
* @param[in] mask bit in the RCC enable register
|
||||
*/
|
||||
void periph_clk_en(uint8_t bus, uint32_t mask);
|
||||
void periph_clk_en(bus_t bus, uint32_t mask);
|
||||
|
||||
/**
|
||||
* @brief Disable the given peripheral clock
|
||||
@ -140,7 +150,7 @@ void periph_clk_en(uint8_t bus, uint32_t mask);
|
||||
* @param[in] bus bus the peripheral is connected to
|
||||
* @param[in] mask bit in the RCC enable register
|
||||
*/
|
||||
void periph_clk_dis(uint8_t bus, uint32_t mask);
|
||||
void periph_clk_dis(bus_t bus, uint32_t mask);
|
||||
|
||||
/**
|
||||
* @brief Configure the given pin to be used as ADC input
|
||||
|
||||
@ -48,15 +48,13 @@ int8_t dac_init(dac_t line)
|
||||
gpio_init_analog(dac_config[line].pin);
|
||||
/* enable the DAC's clock */
|
||||
#if defined(DAC2)
|
||||
RCC->APB1ENR |= dac_config[line].dac
|
||||
? RCC_APB1ENR_DAC2EN
|
||||
: RCC_APB1ENR_DAC1EN;
|
||||
periph_clk_en(APB1, dac_config[line].dac ?
|
||||
RCC_APB1ENR_DAC2EN : RCC_APB1ENR_DAC1EN);
|
||||
#elif defined(DAC1)
|
||||
RCC->APB1ENR |= RCC_APB1ENR_DAC1EN;
|
||||
periph_clk_en(APB1, RCC_APB1ENR_DAC1EN);
|
||||
#else
|
||||
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
||||
periph_clk_en(APB1, RCC_APB1ENR_DACEN);
|
||||
#endif
|
||||
|
||||
/* reset output and enable the line's channel */
|
||||
dac_set(line, 0);
|
||||
dac_poweron(line);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user