121 lines
3.2 KiB
C
121 lines
3.2 KiB
C
/*
|
|
* Kneron System driver
|
|
*
|
|
* Copyright (C) 2019 Kneron, Inc. All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#include "cmsis_os2.h"
|
|
#include "board.h"
|
|
#include "project.h"
|
|
|
|
#include "kdrv_system.h"
|
|
#include "kdrv_scu.h"
|
|
#include "kdrv_scu_ext.h"
|
|
#include "kdrv_power.h"
|
|
#include "kdrv_clock.h"
|
|
#include "kdrv_ddr.h"
|
|
#include "kdrv_pwm.h"
|
|
#include "kdrv_mpu.h"
|
|
|
|
#include "kmdw_console.h"
|
|
#include "kmdw_memxfer.h"
|
|
#include "kmdw_dfu.h"
|
|
#include "kmdw_utils_crc.h"
|
|
#include "kmdw_system.h"
|
|
|
|
extern const struct s_kdp_memxfer kdp_memxfer_module;
|
|
|
|
void system_wakeup_ncpu(int32_t boot_loader_flag, uint8_t wakeup_all)
|
|
{
|
|
if (boot_loader_flag)
|
|
kdrv_pwmtimer_delay_ms(200);
|
|
|
|
if (1 == wakeup_all) {
|
|
kdrv_clock_enable(CLK_SCPU_TRACE);
|
|
kdrv_clock_enable(CLK_NCPU);
|
|
kdrv_clock_enable(CLK_NPU);
|
|
kdrv_system_reset(SUBSYS_PD_NPU);
|
|
kdrv_system_reset(SUBSYS_NPU);
|
|
}
|
|
|
|
SCU_EXTREG_CM4_NCPU_CTRL_SET_wakeup(1);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @brief RELOAD_NCPU_FW(), Reload NCPU firmware from flash
|
|
*/
|
|
void reload_ncpu_fw(void)
|
|
{
|
|
kdrv_mpu_niram_enable();
|
|
int dfu_active_sts = kmdw_dfu_get_active_ncpu_partition();
|
|
kdp_memxfer_module.init(MEMXFER_OPS_DMA, MEMXFER_OPS_DMA);
|
|
kdp_memxfer_module.flash_to_niram(dfu_active_sts);
|
|
kdrv_mpu_niram_disable();
|
|
kdrv_system_reset(SUBSYS_NCPU);
|
|
}
|
|
|
|
/**
|
|
* flag = 0, just launch ncpu
|
|
* flag <> 0, load and launch ncpu
|
|
* flag < 0, not using mpu
|
|
*
|
|
* @retVal: 0, new sum32 value matches with another one in FLASH
|
|
* >0, return wrong new sum32 value
|
|
*/
|
|
u32 load_ncpu_fw(int32_t reset_flag)
|
|
{
|
|
uint32_t ret = 0;
|
|
SCU_EXTREG_CM4_NCPU_CTRL_SET_wakeup(0); // stop ncpu first
|
|
if (reset_flag) {
|
|
if (reset_flag > 0)
|
|
kdrv_mpu_niram_enable();
|
|
/* initialize flash first for kmdw_dfu_get_active_ncpu_partition() */
|
|
kdp_memxfer_module.init(MEMXFER_OPS_DMA, MEMXFER_OPS_DMA);
|
|
int dfu_active_sts = kmdw_dfu_get_active_ncpu_partition();
|
|
kdp_memxfer_module.flash_to_niram(dfu_active_sts);
|
|
/*ncpu may change its interrupt vector in NiRAM, which may fail the image check.
|
|
So ncpu check should be done before ncput is waken up and run*/
|
|
ret = system_check_fw_image(NCPU_FW);
|
|
if (reset_flag > 0)
|
|
kdrv_mpu_niram_disable();
|
|
}
|
|
SCU_EXTREG_CM4_NCPU_CTRL_SET_wakeup(1); // restart ncpu
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Calculate sum32 of scpu/ncpu fw and compare to the value which resides at the end of flash
|
|
* N-iRAM(64KB) 0x28000000 ~ 0x2800FFFF
|
|
* S-iRAM(88KB) 0x10102000 ~ 0x10117FFF
|
|
*
|
|
* If sums are the same, return 0 (Note: check value could be zero)
|
|
* Else return wrong calculated value, if value is zero, return 0xffffffff
|
|
*/
|
|
uint32_t system_check_fw_image(int32_t fw_type)
|
|
{
|
|
uint8_t *pBase;
|
|
uint32_t sum32_cal, sum32_in_flash;
|
|
uint32_t size;
|
|
|
|
if(fw_type == SCPU_FW) {
|
|
pBase = (u8 *)SCPU_START_ADDRESS;
|
|
size = (SCPU_IMAGE_SIZE - 4);
|
|
}
|
|
else if(fw_type == NCPU_FW){
|
|
pBase = (u8 *)NCPU_START_ADDRESS;
|
|
size = (NCPU_IMAGE_SIZE - 4);
|
|
}
|
|
|
|
sum32_cal = kmdw_utils_crc_gen_sum32(pBase, size);
|
|
sum32_in_flash = *(u32 *)(pBase + size);
|
|
if (sum32_cal == sum32_in_flash)
|
|
return 0;
|
|
if (sum32_cal == 0)
|
|
sum32_cal--;
|
|
return sum32_cal;
|
|
}
|
|
|