Skip to content

Commit

Permalink
Fixed UART devices in NS-mode, fixed H5 clock
Browse files Browse the repository at this point in the history
  • Loading branch information
danielinux committed Jun 10, 2024
1 parent d71645c commit 23d3505
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 61 deletions.
110 changes: 64 additions & 46 deletions hal/stm32h5.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "hal.h"
#include "hal/stm32h5.h"

#define PLL_SRC_HSE 1

static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates)
{
uint32_t reg = FLASH_ACR;
Expand Down Expand Up @@ -230,14 +232,30 @@ static void clock_pll_on(void)
uint32_t reg32;
uint32_t plln, pllm, pllq, pllp, pllr, hpre, apb1pre, apb2pre, apb3pre, flash_waitstates;

/* Select clock parameters (CPU Speed = 125 MHz) */

#if PLL_SRC_HSE
pllm = 4;
plln = 125; /* TODO: increase to 250 MHz */
plln = 250;
pllp = 2;
pllq = 2;
pllr = 2;
#else
pllm = 1;
plln = 129;
pllp = 2;
pllq = 2;
pllr = 2;
#endif
flash_waitstates = 5;

/* Set voltage scaler */
reg32 = PWR_VOSCR & (~PWR_VOS_MASK);
PWR_VOSCR = reg32 | PWR_VOS_SCALE_0;

/* Wait until scale has changed */
while ((PWR_VOSSR & PWR_VOSRDY) == 0)
;

/* Disable PLL1 */
RCC_CR &= ~RCC_CR_PLL1ON;

Expand All @@ -248,8 +266,9 @@ static void clock_pll_on(void)
/* Set flash wait states */
flash_set_waitstates(flash_waitstates);

#if PLL_SRC_HSE
/* PLL Oscillator configuration */
RCC_CR |= RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_HSEEXT;
RCC_CR |= RCC_CR_HSEON | RCC_CR_HSEBYP;

/* Wait until HSE is Ready */
while ((RCC_CR & RCC_CR_HSERDY) == 0)
Expand All @@ -260,6 +279,26 @@ static void clock_pll_on(void)
reg32 &= ~((0x3F << RCC_PLLCFGR_PLLM_SHIFT) | (0x03));
reg32 |= (pllm << RCC_PLLCFGR_PLLM_SHIFT) | RCC_PLLCFGR_PLLSRC_HSE;
RCC_PLL1CFGR = reg32;
#else
RCC_CR |= RCC_CR_HSION;

/* Wait until HSI is Ready */
while ((RCC_CR & RCC_CR_HSIRDY) == 0)
;

RCC_CR |= RCC_CR_CSION;

/* Wait until CSI is Ready */
while ((RCC_CR & RCC_CR_HSIRDY) == 0)
;

/* Configure PLL1 div/mul factors */
reg32 = RCC_PLL1CFGR;
reg32 &= ~((0x3F << RCC_PLLCFGR_PLLM_SHIFT) | (0x03));
reg32 |= (pllm << RCC_PLLCFGR_PLLM_SHIFT) | RCC_PLLCFGR_PLLSRC_CSI;
RCC_PLL1CFGR = reg32;

#endif
DMB();

RCC_PLL1DIVR = ((plln - 1) << RCC_PLLDIVR_DIVN_SHIFT) | ((pllp - 1) << RCC_PLLDIVR_DIVP_SHIFT) |
Expand All @@ -281,7 +320,7 @@ static void clock_pll_on(void)
DMB();

/* Select PLL1 Input frequency range: VCI */
RCC_PLL1CFGR |= RCC_PLLCFGR_RGE_1_2 << RCC_PLLCFGR_PLLRGE_SHIFT;
RCC_PLL1CFGR |= RCC_PLLCFGR_RGE_2_4 << RCC_PLLCFGR_PLLRGE_SHIFT;

/* Select PLL1 Output frequency range: VCO = 0 */
RCC_PLL1CFGR &= ~RCC_PLLCFGR_PLLVCOSEL;
Expand Down Expand Up @@ -321,47 +360,8 @@ static void clock_pll_on(void)
while ((RCC_CFGR1 & (RCC_CFGR1_SW_PLL1 << RCC_CFGR1_SWS_SHIFT)) == 0)
;

/* Configure PLL2 div/mul factors */
reg32 = RCC_PLL2CFGR;
reg32 &= ~((0x3F << RCC_PLLCFGR_PLLM_SHIFT) | (0x03));
reg32 |= (pllm << RCC_PLLCFGR_PLLM_SHIFT) | RCC_PLLCFGR_PLLSRC_HSE;
RCC_PLL2CFGR = reg32;
DMB();

RCC_PLL2DIVR = ((plln - 1) << RCC_PLLDIVR_DIVN_SHIFT) | ((pllp - 1) << RCC_PLLDIVR_DIVP_SHIFT) |
((pllq - 1) << RCC_PLLDIVR_DIVQ_SHIFT) | ((pllr - 1) << RCC_PLLDIVR_DIVR_SHIFT);
DMB();


/* Disable Fractional PLL */
RCC_PLL2CFGR &= ~RCC_PLLCFGR_PLLFRACEN;
DMB();


/* Configure Fractional PLL factor */
RCC_PLL2FRACR = 0x00000000;
DMB();

/* Enable Fractional PLL */
RCC_PLL2CFGR |= RCC_PLLCFGR_PLLFRACEN;
DMB();

/* Select PLL2 Input frequency range: VCI */
RCC_PLL2CFGR |= RCC_PLLCFGR_RGE_1_2 << RCC_PLLCFGR_PLLRGE_SHIFT;

/* Select PLL2 Output frequency range: VCO = 0 */
RCC_PLL2CFGR &= ~RCC_PLLCFGR_PLLVCOSEL;
DMB();

/* Enable PLL2 system clock out (DIV: P) */
RCC_PLL2CFGR |= RCC_PLLCFGR_PLLPEN;

/* Enable PLL2 */
RCC_CR |= RCC_CR_PLL2ON;

/* Wait until PLL2 is Ready */
while ((RCC_CR & RCC_CR_PLL2RDY) == 0)
;
/* Set PLL1 as system clock */
RCC_PLL1CFGR |= RCC_PLLCFGR_PLL1PEN;

}

Expand All @@ -374,6 +374,12 @@ static void periph_unsecure(void)
/*Enable clock for User LED GPIOs */
RCC_AHB2_CLOCK_ER|= LED_AHB2_ENABLE;

/* Enable GPIO clock for accessing SECCFGR registers */
RCC_AHB2_CLOCK_ER |= GPIOA_AHB2_CLOCK_ER;
RCC_AHB2_CLOCK_ER |= GPIOB_AHB2_CLOCK_ER;
RCC_AHB2_CLOCK_ER |= GPIOC_AHB2_CLOCK_ER;
RCC_AHB2_CLOCK_ER |= GPIOD_AHB2_CLOCK_ER;

/* Enable clock for LPUART1 */
RCC_APB2_CLOCK_ER |= UART1_APB2_CLOCK_ER_VAL;

Expand Down Expand Up @@ -406,6 +412,15 @@ static void periph_unsecure(void)
TZSC_SECCFGR1 = reg;
}

/* Disable GPIOs clock used previously for accessing SECCFGR registers */
#if 0
RCC_AHB2_CLOCK_ER &= ~GPIOA_AHB2_CLOCK_ER;
RCC_AHB2_CLOCK_ER &= ~GPIOB_AHB2_CLOCK_ER;
RCC_AHB2_CLOCK_ER &= ~GPIOC_AHB2_CLOCK_ER;
RCC_AHB2_CLOCK_ER &= ~GPIOD_AHB2_CLOCK_ER;
#endif


}
#endif

Expand Down Expand Up @@ -500,9 +515,12 @@ void hal_init(void)

void hal_prepare_boot(void)
{
clock_pll_off();

/* Keep clock settings when staging a NS-application */
#if (TZ_SECURE())
periph_unsecure();
#else
clock_pll_off();
#endif
}

Expand Down
15 changes: 10 additions & 5 deletions hal/stm32h5.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
#define RCC_PLL2FRACR (*(volatile uint32_t *)(RCC_BASE + 0x40)) /* RM0481 - Table 108 */

#define RCC_PLLCFGR_PLLSRC_SHIFT (0x0)
#define RCC_PLLCFGR_PLLSRC_HSI (0x1)
#define RCC_PLLCFGR_PLLSRC_CSI (0x2)
#define RCC_PLLCFGR_PLLSRC_HSE (0x3)
#define RCC_PLLCFGR_PLLRGE_SHIFT (0x2)
#define RCC_PLLCFGR_RGE_1_2 (0x0) /* Default at boot: 1-2 MHz */
Expand Down Expand Up @@ -153,10 +155,10 @@

#define RCC_CCIPR1 (*(volatile uint32_t *)(RCC_BASE + 0xD8))
#define RCC_CCIPR3 (*(volatile uint32_t *)(RCC_BASE + 0xE0))
#define RCC_CCIPR3_LPUART1SEL_SHIFT (24)
#define RCC_CCIPR3_LPUART1SEL_MASK (0x3)
#define RCC_CCIPR1_USART3SEL_SHIFT (6)
#define RCC_CCIPR1_USART3SEL_MASK (0x3)
#define RCC_CCIPR1_USART3SEL_MASK (0x7)
#define RCC_CCIPR3_LPUART1SEL_SHIFT (24)
#define RCC_CCIPR3_LPUART1SEL_MASK (0x7)


#define RCC_CRRCR (*(volatile uint32_t *)(RCC_BASE + 0x98))
Expand All @@ -167,10 +169,10 @@
/*!< Memory & Instance aliases and base addresses for Non-Secure/Secure peripherals */
#if TZ_SECURE()
/*Secure */
#define PWR_BASE (0x50020800) //RM0481 - Table 3
#define PWR_BASE (0x54020800) //RM0481 - Table 3
#else
/*Non-Secure */
#define PWR_BASE (0x40020800) //RM0481 - Table 3
#define PWR_BASE (0x44020800) //RM0481 - Table 3
#endif

#define PWR_VOSCR (*(volatile uint32_t *)(PWR_BASE + 0x10))
Expand Down Expand Up @@ -382,6 +384,7 @@
#define UART1_ICR (*(volatile uint32_t *)(UART1 + 0x20))
#define UART1_RDR (*(volatile uint32_t *)(UART1 + 0x24))
#define UART1_TDR (*(volatile uint32_t *)(UART1 + 0x28))
#define UART1_PRE (*(volatile uint32_t *)(UART1 + 0x2C))

#define UART3_CR1 (*(volatile uint32_t *)(UART3 + 0x00))
#define UART3_CR2 (*(volatile uint32_t *)(UART3 + 0x04))
Expand All @@ -391,8 +394,10 @@
#define UART3_ICR (*(volatile uint32_t *)(UART3 + 0x20))
#define UART3_RDR (*(volatile uint32_t *)(UART3 + 0x24))
#define UART3_TDR (*(volatile uint32_t *)(UART3 + 0x28))
#define UART3_PRE (*(volatile uint32_t *)(UART3 + 0x2C))

#define UART_CR1_UART_ENABLE (1 << 0)
#define UART_CR1_OVER8 (1 << 15)
#define UART_CR1_SYMBOL_LEN (1 << 12)
#define UART_CR1_PARITY_ENABLED (1 << 10)
#define UART_CR1_PARITY_ODD (1 << 9)
Expand Down
29 changes: 19 additions & 10 deletions hal/uart/uart_drv_stm32h5.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@

/* USE_UART1
* Set to 0 for VCP over USB
* Set to 1 for Arduino D0, D1 pins on nucleo
* Set to 1 for Arduino D0, D1 pins on nucleo
* */
#define USE_UART1 0

#define RCC_AHB2ENR1_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0x8C ))
#define GPIOB_AHB2ENR1_CLOCK_ER (1 << 1)
#define GPIOD_AHB2ENR1_CLOCK_ER (1 << 3)


#define GPIOB_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00))
#define GPIOB_OTYPE (*(volatile uint32_t *)(GPIOB_BASE + 0x04))
Expand All @@ -53,18 +57,18 @@
#define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20))
#define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24))

//#define CLOCK_FREQ (125000000)
#define CLOCK_FREQ (64000000)

static void uart1_pins_setup(void)
{
uint32_t reg;
RCC_AHB2ENR1_CLOCK_ER|= GPIOB_AHB2ENR1_CLOCK_ER;
/* Set mode = AF */
reg = GPIOB_MODE & ~ (0x03 << (UART1_RX_PIN * 2));
GPIOB_MODE = reg | (2 << (UART1_RX_PIN * 2));
reg = GPIOB_MODE & ~ (0x03 << (UART1_TX_PIN * 2));
GPIOB_MODE = reg | (2 << (UART1_TX_PIN * 2));

/* Alternate function: use low pins (6 and 7) */
reg = GPIOB_AFL & ~(0xf << (UART1_TX_PIN * 4));
GPIOB_AFL = reg | (UART1_PIN_AF << (UART1_TX_PIN * 4));
Expand All @@ -76,12 +80,13 @@ static void uart1_pins_setup(void)
static void uart3_pins_setup(void)
{
uint32_t reg;
RCC_AHB2ENR1_CLOCK_ER|= GPIOD_AHB2ENR1_CLOCK_ER;
/* Set mode = AF */
reg = GPIOD_MODE & ~ (0x03 << (UART3_RX_PIN * 2));
GPIOD_MODE = reg | (2 << (UART3_RX_PIN * 2));
reg = GPIOD_MODE & ~ (0x03 << (UART3_TX_PIN * 2));
GPIOD_MODE = reg | (2 << (UART3_TX_PIN * 2));

/* Alternate function: use hi pins (8 and 9) */
reg = GPIOD_AFH & ~(0xf << ((UART3_TX_PIN - 8) * 4));
GPIOD_AFH = reg | (UART3_PIN_AF << ((UART3_TX_PIN - 8) * 4));
Expand All @@ -97,10 +102,10 @@ static int uart1_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
uart1_pins_setup();

reg = RCC_CCIPR3 & (~ (RCC_CCIPR3_LPUART1SEL_MASK << RCC_CCIPR3_LPUART1SEL_SHIFT));
RCC_CCIPR3 = reg | (3 << RCC_CCIPR3_LPUART1SEL_SHIFT); /* PLL2 */
RCC_CCIPR3 = reg | (0 << RCC_CCIPR3_LPUART1SEL_SHIFT); /* PLL2 */

/* Configure clock */
UART1_BRR |= (uint16_t)(CLOCK_FREQ / bitrate);
UART1_BRR |= (uint16_t)(CLOCK_FREQ / bitrate) + 1;

/* Configure data bits */
if (data == 8)
Expand All @@ -126,7 +131,9 @@ static int uart1_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
UART1_CR2 = reg & (2 << 12);
else
UART1_CR2 = reg;


/* Prescaler to DIV1 */
UART1_PRE |= 2;

/* Configure for RX+TX, turn on. */
UART1_CR1 |= UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE | UART_CR1_UART_ENABLE;
Expand Down Expand Up @@ -163,10 +170,10 @@ static int uart3_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
uart3_pins_setup();

reg = RCC_CCIPR1 & (~ (RCC_CCIPR1_USART3SEL_MASK << RCC_CCIPR1_USART3SEL_SHIFT));
RCC_CCIPR1 = reg | (3 << RCC_CCIPR1_USART3SEL_SHIFT); /* PLL2 */
RCC_CCIPR1 = reg | (0 << RCC_CCIPR1_USART3SEL_SHIFT); /* PLL2 */

/* Configure clock */
UART3_BRR |= (uint16_t)(CLOCK_FREQ / bitrate);
UART3_BRR = (uint16_t)(CLOCK_FREQ / bitrate) + 1;

/* Configure data bits */
if (data == 8)
Expand All @@ -192,7 +199,9 @@ static int uart3_init(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
UART3_CR2 = reg & (2 << 12);
else
UART3_CR2 = reg;


/* Prescaler to DIV1 */
UART3_PRE |= 2;

/* Configure for RX+TX, turn on. */
UART3_CR1 |= UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE | UART_CR1_UART_ENABLE;
Expand Down
2 changes: 2 additions & 0 deletions test-app/app_stm32h5.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ extern const CK_FUNCTION_LIST wolfpkcs11nsFunctionList;
#define GPIOG_AHB2ENR1_CLOCK_ER (1 << 6)
#define GPIOF_AHB2ENR1_CLOCK_ER (1 << 5)
#define GPIOB_AHB2ENR1_CLOCK_ER (1 << 1)
#define GPIOD_AHB2ENR1_CLOCK_ER (1 << 3)

static void boot_led_on(void)
{
Expand Down Expand Up @@ -154,6 +155,7 @@ void main(void)

/* Turn on boot LED */
boot_led_on();

uart_init(115200, 8, 'N', 1);
for (i = 0; i < 10000; i++) {
uart_tx('T');
Expand Down

0 comments on commit 23d3505

Please sign in to comment.