Skip to content

Commit

Permalink
Merge pull request #309 from Paciente8159/308-bug-stm32-uart-incorrec…
Browse files Browse the repository at this point in the history
…t-baudrate

STM32 peripheral clocks now calculated from APB settings
  • Loading branch information
Paciente8159 committed Oct 17, 2022
2 parents e29738a + 50bef8e commit dc09149
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 40 deletions.
1 change: 1 addition & 0 deletions uCNC/src/hal/boards/stm32/stm32.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[common_stm32]
platform = ststm32
; debug with st-link
; upload_protocol = cmsis-dap
platform_packages = platformio/tool-openocd
debug_build_flags = -Og -g3 -ggdb3 -gdwarf-2
debug_init_cmds =
Expand Down
29 changes: 12 additions & 17 deletions uCNC/src/hal/mcus/stm32f1x/mcu_stm32f1x.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,15 +350,9 @@ void osSystickHandler(void)
static void mcu_rtc_init(void);
static void mcu_usart_init(void);

#if (INTERFACE == INTERFACE_UART)
#define APB2_PRESCALER RCC_CFGR_PPRE2_DIV2
#else
#define APB2_PRESCALER RCC_CFGR_PPRE2_DIV1
#endif

#ifndef FRAMEWORK_CLOCKS_INIT
void mcu_clocks_init()
{
#ifndef FRAMEWORK_CLOCKS_INIT
/* Reset the RCC clock configuration to the default reset state */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
Expand All @@ -382,8 +376,7 @@ void mcu_clocks_init()
* If crystal is 16MHz, add in PLLXTPRE flag to prescale by 2
*/
RCC->CFGR = (uint32_t)(RCC_CFGR_HPRE_DIV1 |
APB2_PRESCALER |
RCC_CFGR_PPRE1_DIV2 |
APB1_PRESC | APB2_PRESC |
RCC_CFGR_PLLSRC |
RCC_CFGR_PLLMULL9);
/* Enable PLL */
Expand All @@ -396,8 +389,11 @@ void mcu_clocks_init()
/* Wait till PLL is used as system clock source */
while (!(RCC->CFGR & (uint32_t)RCC_CFGR_SWS))
;
}
#else
RCC->CFGR &= ~(RCC_CFGR_PPRE1_Msk | RCC_CFGR_PPRE2_Msk);
RCC->CFGR |= (APB1_PRESC | APB2_PRESC);
#endif
}

void mcu_usart_init(void)
{
Expand All @@ -415,7 +411,7 @@ void mcu_usart_init(void)
COM_USART->CR3 = 0;
COM_USART->SR = 0;
// //115200 baudrate
float baudrate = ((float)(F_CPU >> 5) / ((float)BAUDRATE));
float baudrate = ((float)(PERIPH_CLOCK >> 4) / ((float)BAUDRATE));
uint16_t brr = (uint16_t)baudrate;
baudrate -= brr;
brr <<= 4;
Expand Down Expand Up @@ -487,10 +483,7 @@ void mcu_putc(char c)

void mcu_init(void)
{
// make sure both APB1 and APB2 are running at the same clock (36MHz)
#ifndef FRAMEWORK_CLOCKS_INIT
mcu_clocks_init();
#endif
stm32_flash_current_page = -1;
stm32_global_isr_enabled = false;
mcu_io_init();
Expand Down Expand Up @@ -620,7 +613,9 @@ char mcu_getc(void)
void mcu_freq_to_clocks(float frequency, uint16_t *ticks, uint16_t *prescaller)
{
// up and down counter (generates half the step rate at each event)
uint32_t totalticks = (uint32_t)((float)(F_CPU >> 2) / frequency);
uint32_t totalticks = (uint32_t)((float)(F_CPU >> 1) / frequency);

totalticks >>= 1;
*prescaller = 1;
while (totalticks > 0xFFFF)
{
Expand Down Expand Up @@ -830,7 +825,8 @@ void mcu_eeprom_flush()
void mcu_spi_config(uint8_t mode, uint32_t frequency)
{
mode = CLAMP(0, mode, 4);
uint8_t div = (uint8_t)(F_CPU / frequency);
uint8_t div = (uint8_t)(PERIPH_CLOCK / frequency);

uint8_t speed;
if (div < 2)
{
Expand Down Expand Up @@ -980,7 +976,6 @@ void MCU_ONESHOT_ISR(void)
#ifndef mcu_config_timeout
void mcu_config_timeout(mcu_timeout_delgate fp, uint32_t timeout)
{
// up and down counter (generates half the step rate at each event)
uint32_t clocks = (uint32_t)((F_CPU / 1000000UL) * timeout);
uint32_t presc = 1;

Expand Down
17 changes: 14 additions & 3 deletions uCNC/src/hal/mcus/stm32f1x/mcumap_stm32f1x.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ extern "C"
#define ENABLE_SYNC_RX
#endif

// APB1 cannot exceed 36MHz
#if (F_CPU > 36000000UL)
#define APB1_PRESC RCC_CFGR_PPRE1_DIV2
#define APB2_PRESC RCC_CFGR_PPRE2_DIV2
#define PERIPH_CLOCK (F_CPU>>1)
#else
#define APB1_PRESC RCC_CFGR_PPRE1_DIV1
#define APB2_PRESC RCC_CFGR_PPRE2_DIV2
#define PERIPH_CLOCK F_CPU
#endif

// Helper macros
#define __helper_ex__(left, mid, right) left##mid##right
#define __helper__(left, mid, right) __helper_ex__(left, mid, right)
Expand Down Expand Up @@ -4285,7 +4296,7 @@ extern "C"

#define I2C_APBEN __helper__(RCC_APB1ENR_I2C, I2C_PORT, EN)
#define I2C_REG __helper__(I2C, I2C_PORT, )
#define I2C_SPEEDRANGE ((F_CPU >> 1) / 1000000UL)
#define I2C_SPEEDRANGE (PERIPH_CLOCK / 1000000UL)

#if ((I2C_PORT == 1) && (I2C_SCL_PORT == B6) && (I2C_SDA_PORT == B7))
#elif ((I2C_PORT == 1) && (I2C_SCL_PORT == B8) && (I2C_SDA_PORT == B9))
Expand Down Expand Up @@ -4555,7 +4566,7 @@ extern "C"
#define mcu_get_pwm(diopin) ((uint8_t)((((uint32_t)__indirect__(diopin, TIMREG)->__indirect__(diopin, CCR)) * 255) / ((uint32_t)__indirect__(diopin, TIMREG)->ARR)))

#define mcu_get_analog(diopin) \
({ \
({ \
ADC1->SQR3 = __indirect__(diopin, CHANNEL); \
ADC1->CR2 |= ADC_CR2_SWSTART; \
ADC1->CR2 &= ~ADC_CR2_SWSTART; \
Expand Down Expand Up @@ -4586,7 +4597,7 @@ extern "C"
#endif
#endif

extern volatile bool stm32_global_isr_enabled;
extern volatile bool stm32_global_isr_enabled;
#define mcu_enable_global_isr() \
{ \
__enable_irq(); \
Expand Down
28 changes: 13 additions & 15 deletions uCNC/src/hal/mcus/stm32f4x/mcu_stm32f4x.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "core_cm4.h"
#include "stm32f4xx.h"
#include "mcumap_stm32f4x.h"
#include <math.h>

#if (INTERFACE == INTERFACE_USB)
#include "../../../tinyusb/tusb_config.h"
Expand Down Expand Up @@ -330,12 +331,6 @@ void osSystickHandler(void)
static void mcu_rtc_init(void);
static void mcu_usart_init(void);

#if (INTERFACE == INTERFACE_UART)
#define APB2_PRESCALER RCC_CFGR_PPRE2_DIV2
#else
#define APB2_PRESCALER RCC_CFGR_PPRE2_DIV1
#endif

#ifndef FRAMEWORK_CLOCKS_INIT
#if (F_CPU == 84000000)
#define PLLN 336
Expand All @@ -348,9 +343,10 @@ static void mcu_usart_init(void);
#else
#error "Running the CPU at this frequency might lead to unexpected behaviour"
#endif

#endif
void mcu_clocks_init()
{
#ifndef FRAMEWORK_CLOCKS_INIT
// enable power clock
SETFLAG(RCC->APB1ENR, RCC_APB1ENR_PWREN);
// set voltage regulator scale 2
Expand Down Expand Up @@ -389,7 +385,7 @@ void mcu_clocks_init()
/* HCLK = SYSCLK, PCLK2 = HCLK, PCLK1 = HCLK / 2
* If crystal is 16MHz, add in PLLXTPRE flag to prescale by 2
*/
SETFLAG(RCC->CFGR, (uint32_t)(RCC_CFGR_HPRE_DIV1 | APB2_PRESCALER | RCC_CFGR_PPRE1_DIV2));
SETFLAG(RCC->CFGR, (uint32_t)(RCC_CFGR_HPRE_DIV1 | APB2_PRESC | APB1_PRESC));

/* Select PLL as system clock source */
CLEARFLAG(RCC->CFGR, RCC_CFGR_SW);
Expand All @@ -409,9 +405,12 @@ void mcu_clocks_init()
// DWT->CYCCNT = 0;
// DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
// }
}

#else
RCC->CFGR &= ~(RCC_CFGR_PPRE1_Msk | RCC_CFGR_PPRE2_Msk);
RCC->CFGR |= (APB2_PRESC | APB1_PRESC);
#endif
}

void mcu_usart_init(void)
{
Expand All @@ -425,8 +424,8 @@ void mcu_usart_init(void)
COM_USART->CR2 = 0; // 1 stop bit STOP=00
COM_USART->CR3 = 0;
COM_USART->SR = 0;
// //115200 baudrate
float baudrate = ((float)(F_CPU >> 1) / ((float)(BAUDRATE * 8 * 2)));
// //115200 baudrate
float baudrate = ((float)(PERIPH_CLOCK >> 4) / ((float)(BAUDRATE)));
uint16_t brr = (uint16_t)baudrate;
baudrate -= brr;
brr <<= 4;
Expand Down Expand Up @@ -512,10 +511,8 @@ void mcu_putc(char c)

void mcu_init(void)
{
// make sure both APB1 and APB2 are running at the same clock (48MHz)
#ifndef FRAMEWORK_CLOCKS_INIT
// make sure both APB1 and APB2 are running at the same clock (48MHz)
mcu_clocks_init();
#endif
stm32_flash_current_page = -1;
stm32_global_isr_enabled = false;
mcu_io_init();
Expand Down Expand Up @@ -885,7 +882,8 @@ void mcu_eeprom_flush()
void mcu_spi_config(uint8_t mode, uint32_t frequency)
{
mode = CLAMP(0, mode, 4);
uint8_t div = (uint8_t)(F_CPU / frequency);
uint8_t div = (uint8_t)(PERIPH_CLOCK / frequency);

uint8_t speed;
if (div < 2)
{
Expand Down
25 changes: 20 additions & 5 deletions uCNC/src/hal/mcus/stm32f4x/mcumap_stm32f4x.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ extern "C"
#define ENABLE_SYNC_RX
#endif

// APB1 cannot exceed 36MHz
#if (F_CPU > 90000000UL)
#define APB1_PRESC RCC_CFGR_PPRE1_DIV4
#define APB2_PRESC RCC_CFGR_PPRE2_DIV4
#define PERIPH_CLOCK (F_CPU >> 2)
#elif (F_CPU > 45000000UL)
#define APB1_PRESC RCC_CFGR_PPRE1_DIV2
#define APB2_PRESC RCC_CFGR_PPRE2_DIV2
#define PERIPH_CLOCK (F_CPU >> 1)
#else
#define APB1_PRESC RCC_CFGR_PPRE1_DIV1
#define APB2_PRESC RCC_CFGR_PPRE2_DIV1
#define PERIPH_CLOCK F_CPU
#endif

// Helper macros
#define __helper_ex__(left, mid, right) left##mid##right
#define __helper__(left, mid, right) __helper_ex__(left, mid, right)
Expand Down Expand Up @@ -3043,7 +3058,7 @@ extern "C"

#define I2C_APBEN __helper__(RCC_APB1ENR_I2C, I2C_PORT, EN)
#define I2C_REG __helper__(I2C, I2C_PORT, )
#define I2C_SPEEDRANGE ((F_CPU >> 1) / 1000000UL)
#define I2C_SPEEDRANGE (PERIPH_CLOCK / 1000000UL)
#define I2C_AFIO 4

#ifndef I2C_FREQ
Expand Down Expand Up @@ -3227,7 +3242,7 @@ extern "C"
__indirect__(diopin, GPIO)->OTYPER |= (1 << ((__indirect__(diopin, BIT)))); \
}

#define mcu_config_pwm(diopin, freq) \
#define mcu_config_pwm(diopin, freq) \
{ \
RCC->AHB1ENR |= __indirect__(diopin, AHB1EN); \
PWM0_ENREG |= PWM0_APBEN; \
Expand All @@ -3237,7 +3252,7 @@ extern "C"
__indirect__(diopin, GPIO)->AFR[(__indirect__(diopin, BIT) >> 3)] |= ((__indirect__(diopin, AF) << ((__indirect__(diopin, BIT) & 0x07) << 2))); /*af mode*/ \
__indirect__(diopin, TIMREG)->CR1 = 0; \
__indirect__(diopin, TIMREG)->PSC = (uint16_t)(F_CPU / 1000000UL) - 1; \
__indirect__(diopin, TIMREG)->ARR = (uint16_t)(1000000UL / freq); \
__indirect__(diopin, TIMREG)->ARR = (uint16_t)(1000000UL / freq); \
__indirect__(diopin, TIMREG)->__indirect__(diopin, CCR) = 0; \
__indirect__(diopin, TIMREG)->__indirect__(diopin, CCMREG) = __indirect__(diopin, MODE); \
__indirect__(diopin, TIMREG)->CCER |= (1U << ((__indirect__(diopin, CHANNEL) - 1) << 2)); \
Expand Down Expand Up @@ -3296,7 +3311,7 @@ extern "C"
#define mcu_get_pwm(diopin) ((uint8_t)((((uint32_t)__indirect__(diopin, TIMREG)->__indirect__(diopin, CCR)) * 255) / ((uint32_t)__indirect__(diopin, TIMREG)->ARR)))

#define mcu_get_analog(diopin) \
({ \
({ \
ADC1->SQR3 = __indirect__(diopin, CHANNEL); \
ADC1->CR2 |= ADC_CR2_SWSTART; \
ADC1->CR2 &= ~ADC_CR2_SWSTART; \
Expand All @@ -3307,7 +3322,7 @@ extern "C"
})

#define mcu_spi_xmit(X) \
({ \
({ \
SPI_REG->DR = X; \
while (!(SPI1->SR & SPI_SR_TXE) && !(SPI1->SR & SPI_SR_RXNE)) \
; \
Expand Down

0 comments on commit dc09149

Please sign in to comment.