Fire_HPM6750_Template/board/board.c

228 lines
7.2 KiB
C

/* SDK drivers */
#include "hpm_clock_drv.h"
#include "hpm_femc_drv.h"
#include "hpm_i2c_drv.h"
#include "hpm_lcdc_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_sdram_init();
board_pmp_init();
board_lcd_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, PLLCTL_PLL_PLL0, 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_add_to_group(clock_uart0, 0);
clock_set_source_divider(clock_uart0, clk_src_osc24m, 1U);
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_sdram_init(void) {
femc_config_t cfg;
femc_sdram_config_t sdram_cfg;
board_sdram_pins_init();
clock_add_to_group(clock_femc, 0);
clock_set_source_divider(clock_femc, clk_src_pll2_clk0, 2U);
femc_default_config(HPM_FEMC, &cfg);
cfg.dqs = FEMC_DQS_INTERNAL;
femc_init(HPM_FEMC, &cfg);
sdram_cfg.bank_num = FEMC_SDRAM_BANK_NUM_4;
sdram_cfg.prescaler = 3;
sdram_cfg.burst_len_in_byte = 8;
sdram_cfg.auto_refresh_count_in_one_burst = 1;
sdram_cfg.col_addr_bits = FEMC_SDRAM_COLUMN_ADDR_9_BITS;
sdram_cfg.cas_latency = FEMC_SDRAM_CAS_LATENCY_3;
sdram_cfg.precharge_to_act_in_ns = 18;
sdram_cfg.act_to_rw_in_ns = 18;
sdram_cfg.refresh_recover_in_ns = 72;
sdram_cfg.write_recover_in_ns = 12;
sdram_cfg.cke_off_in_ns = 42;
sdram_cfg.act_to_precharge_in_ns = 42;
sdram_cfg.self_refresh_recover_in_ns = 72;
sdram_cfg.refresh_recover_in_ns = 72;
sdram_cfg.act_to_act_in_ns = 12;
sdram_cfg.idle_timeout_in_ns = 6;
sdram_cfg.cs_mux_pin = FEMC_IO_MUX_NOT_USED;
sdram_cfg.cs = FEMC_SDRAM_CS0;
sdram_cfg.base_address = BOARD_SDRAM_BASE;
sdram_cfg.size_in_byte = BOARD_SDRAM_SIZE;
sdram_cfg.port_size = FEMC_SDRAM_PORT_SIZE_16_BITS;
sdram_cfg.refresh_count = 8192;
sdram_cfg.refresh_in_ms = 64;
sdram_cfg.data_width_in_byte = 2;
sdram_cfg.delay_cell_value = 29;
femc_config_sdram(HPM_FEMC, clock_get_frequency(clock_femc), &sdram_cfg);
}
void board_lcd_init(void) {
lcdc_config_t cfg = {0};
/*
* Fire 5" LCD Parameters:
* Horizontal Resolution: 800
* HBP: 46
* HFP: 210 (16-354)
* Vertical Resolution: 480
* VBP: 23
* VFP: 22 (7-147)
* HSync Pulse Width: 1 (1-40) P-CLK
* VSync Pulse Width: 1 (1-20) HSD
*
* Pixel Clock Frequency: 33.264MHz (@60fps, Typ.)
*/
board_lcd_pins_init();
/* Backlight ON */
gpio_set_pin_output_with_initial(BOARD_LCD_BLK_GPIO_CTRL, BOARD_LCD_BLK_GPIO_INDEX, BOARD_LCD_BLK_GPIO_PIN, 1U);
clock_add_to_group(clock_display, 0);
clock_set_source_divider(clock_display, clk_src_pll4_clk0, 18U); /* 33.0MHz */
/* Bug workaround, seems clock not stable */
clock_cpu_delay_ms(10);
lcdc_get_default_config(HPM_LCDC, &cfg);
cfg.resolution_x = BOARD_LCD_RES_H;
cfg.resolution_y = BOARD_LCD_RES_V;
cfg.hsync.pulse_width = 10;
cfg.hsync.back_porch_pulse = 46;
cfg.hsync.front_porch_pulse = 210;
cfg.vsync.pulse_width = 3;
cfg.vsync.back_porch_pulse = 23;
cfg.vsync.front_porch_pulse = 22;
cfg.control.invert_hsync = false;
cfg.control.invert_vsync = false;
cfg.control.invert_href = false;
cfg.control.invert_pixel_data = false;
cfg.control.invert_pixel_clock = false;
lcdc_init(HPM_LCDC, &cfg);
}
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);
}