/* SDK drivers */ #include "hpm_clock_drv.h" #include "hpm_i2c_drv.h" #include "hpm_pcfg_drv.h" #include "hpm_pllctl_drv.h" #include "hpm_pmp_drv.h" #include "hpm_sysctl_drv.h" /* Board */ #include "board.h" #include "pinmux.h" typedef struct { GPIO_Type *ctl; uint8_t index; uint8_t pin; } board_led_t; static const board_led_t s_board_led_table[BOARD_LED_COUNT] = { {.ctl = BOARD_LED0_GPIO_CTRL, .index = BOARD_LED0_GPIO_INDEX, .pin = BOARD_LED0_GPIO_PIN}, {.ctl = BOARD_LED1_GPIO_CTRL, .index = BOARD_LED1_GPIO_INDEX, .pin = BOARD_LED1_GPIO_PIN}, {.ctl = BOARD_LED2_GPIO_CTRL, .index = BOARD_LED2_GPIO_INDEX, .pin = BOARD_LED2_GPIO_PIN}, }; void board_init(void) { board_clock_init(); board_debug_console_init(); board_led_init(); board_pmp_init(); } void board_clock_init(void) { uint32_t cpu0_freq = clock_get_frequency(clock_cpu0); if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) { /* Configure the External OSC ramp-up time: ~9ms */ pllctl_xtal_set_rampup_time(HPM_PLLCTL, 32UL * 1000UL * 9U); /* Select clock setting preset1 */ sysctl_clock_set_preset(HPM_SYSCTL, sysctl_preset_1); } /* Update DCDC voltage */ pcfg_dcdc_set_voltage(HPM_PCFG, BOARD_CORE_VOLTAGE_MV); if (pllctl_init_int_pll_with_freq(HPM_PLLCTL, 0, BOARD_CPU_FREQ) != status_success) { for (;;) { WFI(); } } clock_set_source_divider(clock_cpu0, clk_src_pll0_clk0, 1); clock_update_core_clock(); } void board_debug_console_init(void) { console_config_t cfg; board_debug_uart_pins_init(); /* Configure the UART clock to 24MHz */ clock_set_source_divider(clock_uart0, clk_src_osc24m, 1U); clock_add_to_group(clock_uart0, 0); cfg.type = CONSOLE_TYPE_UART; cfg.base = HPM_UART0_BASE; cfg.src_freq_in_hz = clock_get_frequency(clock_uart0); cfg.baudrate = BOARD_DEBUG_UART_BAUD; console_init(&cfg); } void board_led_init(void) { board_led_pins_init(); } void board_led_set(uint8_t led_id, bool state) { if (led_id < BOARD_LED_COUNT) { const board_led_t *led = &s_board_led_table[led_id]; gpio_write_pin(led->ctl, led->index, led->pin, !state); } } void board_pmp_init(void) { uint32_t start_addr; uint32_t end_addr; uint32_t length; pmp_entry_t pmp_entry[16]; uint8_t index = 0; /* Init noncachable memory */ extern uint32_t __noncacheable_start__[]; extern uint32_t __noncacheable_end__[]; start_addr = (uint32_t)__noncacheable_start__; end_addr = (uint32_t)__noncacheable_end__; length = end_addr - start_addr; if (length > 0) { /* Ensure the address and the length are power of 2 aligned */ assert((length & (length - 1U)) == 0U); assert((start_addr & (length - 1U)) == 0U); pmp_entry[index].pmp_addr = PMP_NAPOT_ADDR(start_addr, length); pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK); pmp_entry[index].pma_addr = PMA_NAPOT_ADDR(start_addr, length); pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN); index++; } /* Init share memory */ extern uint32_t __share_mem_start__[]; extern uint32_t __share_mem_end__[]; start_addr = (uint32_t)__share_mem_start__; end_addr = (uint32_t)__share_mem_end__; length = end_addr - start_addr; if (length > 0) { /* Ensure the address and the length are power of 2 aligned */ assert((length & (length - 1U)) == 0U); assert((start_addr & (length - 1U)) == 0U); pmp_entry[index].pmp_addr = PMP_NAPOT_ADDR(start_addr, length); pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK); pmp_entry[index].pma_addr = PMA_NAPOT_ADDR(start_addr, length); pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN); index++; } pmp_config(&pmp_entry[0], index); }