#include "gd32_bkp.h" static uint8_t g_bkp_first = 0; void gd32_bkp_init(void){ if (POWER_FIRSTFLAG_VALUE != bkp_read_data(POWER_FIRSTFLAG_REG)){ /* enable PMU and BKPI clocks */ rcu_periph_clock_enable(RCU_BKPI); rcu_periph_clock_enable(RCU_PMU); /* allow access to BKP domain */ pmu_backup_write_enable(); /* reset backup domain */ bkp_deinit(); rcu_osci_on(RCU_IRC40K); rcu_osci_stab_wait(RCU_IRC40K); bkp_write_data(POWER_FIRSTFLAG_REG, POWER_FIRSTFLAG_VALUE); g_bkp_first = 1; }else{ /* allow access to BKP domain */ rcu_periph_clock_enable(RCU_BKPI); rcu_periph_clock_enable(RCU_PMU); pmu_backup_write_enable(); g_bkp_first = 0; } } bool gd32_bkp_first_startup(void){ if(g_bkp_first == 1) return TRUE; else return FALSE; } bool gd32_bkp_btrace_valid(void){ if( bkp_read_data(BACK_TRACE_MAIGC_REG) == BACK_TRACE_MAIGC_VALUE) return TRUE; else return FALSE; } void gd32_bkp_save_backtrace(uint32_t *backtrace, uint32_t stack_over, uint32_t stack_dep, uint16_t line){ uint16_t value = ((stack_over << 8) & 0xFF00) | (stack_dep & 0x00FF); uint32_t index; bkp_data_register_enum trace_reg = BACK_TRACE_CALLTRACE_START_REG; bkp_write_data(BACK_TRACE_MAIGC_REG, BACK_TRACE_MAIGC_VALUE); bkp_write_data(BACK_TRACE_INFO_REG, value); for (index = 0; index < stack_dep; index ++){ uint32_t value = (backtrace[index] >> 16) & 0xFFFF; bkp_write_data(trace_reg, (uint16_t)value); trace_reg ++; value = backtrace[index] & 0xFFFF; bkp_write_data(trace_reg, (uint16_t)value); trace_reg ++; } bkp_write_data(BACK_TRACE_LINE_REG, line); } void gd32_bkp_get_backtrace(uint32_t *backtrace, uint32_t *stack_over, uint32_t *stack_dep, uint16_t *line){ uint16_t value = bkp_read_data(BACK_TRACE_INFO_REG); uint32_t index; *stack_over = (value >> 8) & 0xFF; *stack_dep = value & 0xFF; *stack_dep = *stack_dep > 16 ? 16 : *stack_dep; bkp_data_register_enum trace_reg = BACK_TRACE_CALLTRACE_START_REG; for (index = 0; index < *stack_dep; index++){ uint32_t t_h = bkp_read_data(trace_reg); trace_reg ++; uint32_t t_l = bkp_read_data(trace_reg); trace_reg ++; backtrace[index] = (t_h << 16 & 0xFFFF0000) | (t_l & 0xFFFF); } *line = bkp_read_data(BACK_TRACE_LINE_REG); }