From 3fb9e5fd56a4c64259b1795dcbce0bd3fa26e2b4 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Thu, 24 Aug 2023 13:25:14 -0300 Subject: [PATCH] Update H5 HAL, enable RNG, work at 250MHz, add to tests --- .github/workflows/test.yml | 12 +++++++ .../Makefile | 1 - .../hal.h | 35 ++++++++++++++----- .../main.c | 10 ++++-- .../sysinit.c | 25 ++++++++++++- 5 files changed, 69 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8e868787..c6b4a7b8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -175,6 +175,17 @@ jobs: - if: ${{ env.GO == 1 }} run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6 + test_h5: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: { fetch-depth: 3 } + - run: if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h5.*-make-" ; then echo GO=1 >> $GITHUB_ENV ; fi + - if: ${{ env.GO == 1 }} + run: sudo apt -y update; sudo apt -y install gcc-arm-none-eabi + - if: ${{ env.GO == 1 }} + run: make -C examples/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} + test_tm4c: runs-on: ubuntu-latest steps: @@ -269,6 +280,7 @@ jobs: - path: stm32/nucleo-f746zg-make-freertos-builtin - path: stm32/nucleo-f746zg-make-freertos-tcp - path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis + - path: stm32/nucleo-h563zi-make-baremetal-builtin - path: stm32/nucleo-h743zi-make-baremetal-builtin - path: stm32/nucleo-h743zi-make-freertos-builtin - path: ti/ti-ek-tm4c1294xl-http-server diff --git a/examples/stm32/nucleo-h563zi-make-baremetal-builtin/Makefile b/examples/stm32/nucleo-h563zi-make-baremetal-builtin/Makefile index 57d5bbc9..7163e190 100644 --- a/examples/stm32/nucleo-h563zi-make-baremetal-builtin/Makefile +++ b/examples/stm32/nucleo-h563zi-make-baremetal-builtin/Makefile @@ -28,7 +28,6 @@ all build example: firmware.bin firmware.bin: firmware.elf arm-none-eabi-objcopy -O binary $< $@ - ls -l firmware.* firmware.elf: cmsis_core cmsis_h5 $(SOURCES) hal.h link.ld Makefile arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@ diff --git a/examples/stm32/nucleo-h563zi-make-baremetal-builtin/hal.h b/examples/stm32/nucleo-h563zi-make-baremetal-builtin/hal.h index d6bfe0d0..138b42a8 100644 --- a/examples/stm32/nucleo-h563zi-make-baremetal-builtin/hal.h +++ b/examples/stm32/nucleo-h563zi-make-baremetal-builtin/hal.h @@ -27,10 +27,23 @@ #define LED LED2 // Use yellow LED for blinking -// TODO(cpq): Using HSI clock, 64Mhz. Switch to PLL clock and maximum frequency -#define CPU_FREQUENCY 64000000 -#define APB2_FREQUENCY CPU_FREQUENCY -#define APB1_FREQUENCY CPU_FREQUENCY +// System clock (11.4, Figure 48; 11.4.5, Figure 51; 11.4.8 +// CPU_FREQUENCY <= 250 MHz; (SYS_FREQUENCY / HPRE) ; hclk = CPU_FREQUENCY +// APB clocks <= 250 MHz. Configure flash latency (WS) in accordance to hclk +// freq (7.3.4, Table 37) +enum { + HPRE = 7, // register value, divisor value = BIT(value - 7) = / 1 + PPRE1 = 4, // register values, divisor value = BIT(value - 3) = / 2 + PPRE2 = 4, + PPRE3 = 4, +}; +// Make sure your chip package uses the internal LDO, otherwise set PLL1_N = 200 +enum { PLL1_HSI = 64, PLL1_M = 32, PLL1_N = 250, PLL1_P = 2 }; +#define FLASH_LATENCY 0x25 // WRHIGHFREQ LATENCY +#define CPU_FREQUENCY ((PLL1_HSI * PLL1_N / PLL1_M / PLL1_P / (BIT(HPRE - 7))) * 1000000) +#define AHB_FREQUENCY CPU_FREQUENCY +#define APB2_FREQUENCY (AHB_FREQUENCY / (BIT(PPRE2 - 3))) +#define APB1_FREQUENCY (AHB_FREQUENCY / (BIT(PPRE1 - 3))) static inline void spin(volatile uint32_t n) { while (n--) (void) 0; @@ -123,13 +136,17 @@ static inline uint8_t uart_read_byte(USART_TypeDef *uart) { } static inline void rng_init(void) { + RCC->CCIPR5 |= RCC_CCIPR5_RNGSEL_0; // RNG clock source pll1_q_ck RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; // Enable RNG clock RNG->CR |= RNG_CR_RNGEN; // Enable RNG } static inline uint32_t rng_read(void) { - // while ((RNG->SR & RNG_SR_DRDY) == 0) spin(1); - // return RNG->DR; - return rand(); + while ((RNG->SR & RNG_SR_DRDY) == 0) spin(1); + return RNG->DR; +} + +static inline bool ldo_is_on(void) { + return (PWR->SCCR & PWR_SCCR_LDOEN) == PWR_SCCR_LDOEN; } static inline void ethernet_init(void) { @@ -147,9 +164,9 @@ static inline void ethernet_init(void) { RCC->AHB1ENR |= RCC_AHB1ENR_ETHEN | RCC_AHB1ENR_ETHRXEN | RCC_AHB1ENR_ETHTXEN; } -#define UUID ((uint32_t *) UID_BASE) // Unique 96-bit chip ID +#define UUID ((uint32_t *) UID_BASE) // Unique 96-bit chip ID. TRM 59.1 -// Helper macro for MAC generation +// Helper macro for MAC generation, byte reads not allowed #define GENERATE_LOCALLY_ADMINISTERED_MAC() \ { \ 2, UUID[0] & 255, (UUID[0] >> 10) & 255, (UUID[0] >> 19) & 255, \ diff --git a/examples/stm32/nucleo-h563zi-make-baremetal-builtin/main.c b/examples/stm32/nucleo-h563zi-make-baremetal-builtin/main.c index 70e6a44a..4c849dc2 100644 --- a/examples/stm32/nucleo-h563zi-make-baremetal-builtin/main.c +++ b/examples/stm32/nucleo-h563zi-make-baremetal-builtin/main.c @@ -23,7 +23,7 @@ void mg_random(void *buf, size_t len) { // Use on-board RNG } } -void timer_fn(void *arg) { +static void timer_fn(void *arg) { gpio_toggle(LED); // Blink LED struct mg_tcpip_if *ifp = arg; // And show const char *names[] = {"down", "up", "req", "ready"}; // network stats @@ -43,7 +43,7 @@ int main(void) { mg_log_set(MG_LL_DEBUG); // Set log level // Initialise Mongoose network stack - struct mg_tcpip_driver_stm32h_data driver_data = {.mdc_cr = 0}; + struct mg_tcpip_driver_stm32h_data driver_data = {.mdc_cr = 4}; struct mg_tcpip_if mif = {.mac = GENERATE_LOCALLY_ADMINISTERED_MAC(), // Uncomment below for static configuration: // .ip = mg_htonl(MG_U32(192, 168, 0, 223)), @@ -52,16 +52,20 @@ int main(void) { .driver = &mg_tcpip_driver_stm32h, .driver_data = &driver_data}; mg_tcpip_init(&mgr, &mif); + mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif); + MG_INFO(("MAC: %M. Waiting for IP...", mg_print_mac, mif.mac)); while (mif.state != MG_TCPIP_STATE_READY) { mg_mgr_poll(&mgr, 0); } - mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif); + MG_INFO(("Initialising application...")); web_init(&mgr); + MG_INFO(("Starting event loop")); for (;;) { mg_mgr_poll(&mgr, 0); } + return 0; } diff --git a/examples/stm32/nucleo-h563zi-make-baremetal-builtin/sysinit.c b/examples/stm32/nucleo-h563zi-make-baremetal-builtin/sysinit.c index e07d95e0..4d84f947 100644 --- a/examples/stm32/nucleo-h563zi-make-baremetal-builtin/sysinit.c +++ b/examples/stm32/nucleo-h563zi-make-baremetal-builtin/sysinit.c @@ -11,8 +11,31 @@ uint32_t SystemCoreClock = CPU_FREQUENCY; void SystemInit(void) { // Called automatically by startup code SCB->CPACR |= ((3UL << 20U) | (3UL << 22U)); // Enable FPU - RCC->CR = RCC_CR_HSION; // Clear HSI clock divisor. SYS clock 64Mhz + asm("DSB"); + asm("ISB"); + if (ldo_is_on()) { + PWR->VOSCR = PWR_VOSCR_VOS_0 | PWR_VOSCR_VOS_1; // Select VOS0 + } else { + PWR->VOSCR = PWR_VOSCR_VOS_1; // Select VOS1 + } + uint32_t f = PWR->VOSCR; // fake read to wait for bus clocking + while ((PWR->VOSSR & PWR_VOSSR_ACTVOSRDY) == 0) spin(1); + (void) f; + FLASH->ACR |= FLASH_LATENCY; + RCC->CR = RCC_CR_HSION; // Clear HSI clock divisor while ((RCC->CR & RCC_CR_HSIRDY) == 0) spin(1); // Wait until done + RCC->CFGR2 = (PPRE3 << 12) | (PPRE2 << 8) | (PPRE1 << 4) | (HPRE << 0); + RCC->PLL1DIVR = + ((PLL1_P - 1) << 9) | ((PLL1_N - 1) << 0); // Set PLL1_P PLL1_N + // Enable P and Q divider outputs; set PLL1_M, select HSI as source, + // !PLL1VCOSEL, PLL1RGE=0 + RCC->PLL1CFGR = + RCC_PLL1CFGR_PLL1QEN | RCC_PLL1CFGR_PLL1PEN | (PLL1_M << 8) | (1 << 0); + RCC->CR |= RCC_CR_PLL1ON; // Enable PLL1 + while ((RCC->CR & RCC_CR_PLL1RDY) == 0) spin(1); // Wait until done + RCC->CFGR1 |= (3 << 0); // Set clock source to PLL1 + while ((RCC->CFGR1 & (7 << 3)) != (3 << 3)) spin(1); // Wait until done + rng_init(); // Initialise random number generator SysTick_Config(CPU_FREQUENCY / 1000); // Sys tick every 1ms }