Fire_HPM6750_Template/board/board.c

128 lines
4.0 KiB
C

/* 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);
}