#ifndef _DRV_NVM_H_ #define _DRV_NVM_H_ #include #define NVM_VERSION 0x03 #define NVM_LANG_CN 0 #define NVM_LANG_EN 1 #define NVM_USB_MIDI 0 #define NVM_USB_UPDATE 1 #ifndef FLASH_BASE #define FLASH_BASE 0x08000000UL #endif #define fwname "BRS08L\x00" #define fwdata __DATE__ #define fwtime __TIME__ /* 参数固定在 0x0803FC00(256KB 末尾倒数第 2 个 1KB)。 * 地址不能跟 SECTOR_SIZE 走:App 与 Boot 对该宏不一致时,Boot 会读错, * USB 更新标志对不上。AT32F403A 扇区是 2KB,擦除必须对齐扇区起点, * 否则 0->1(MIDI->更新)写不进去。应用程序链接范围必须停在该扇区之前。 */ #define NVM_FLASH_SECTOR 2048UL #define INNER_FLASH_SAVE_ADDRESS (FLASH_BASE + 0x00040000UL - 1024UL) #define INNER_FLASH_SECTOR_ADDRESS (INNER_FLASH_SAVE_ADDRESS & ~(NVM_FLASH_SECTOR - 1UL)) /* 备份寄存器在系统复位后仍保留。确认 USB 更新时先写下这个值, * Boot 即使没读到 Flash 里的 UsbMode,不按圆键 4 也会停在烧录模式。 */ #define NVM_USB_BOOT_MAGIC 0xB007u #pragma pack(push, 1) typedef struct { uint16_t BPM; uint8_t Timbre; uint8_t BandVol; uint8_t StringVol; uint8_t MIcVol; uint8_t MicRev; uint8_t AutoCloseTime; uint8_t Transpose; uint8_t BluetoothSW; /* 0=关 1=开 */ uint8_t Param1; uint8_t Param2; uint8_t Param3; uint8_t Language; /* 0=中文 1=English;本轮仅记忆,不切全机文案 */ uint8_t UsbMode; /* 0=USB MIDI 1=USB更新 */ } DeviceParam_Type; typedef struct { uint8_t Signature[4]; uint8_t Name[12]; uint8_t Data[16]; uint8_t Time[16]; uint8_t nvm_version; uint8_t lock_mcu_flash; uint8_t lock_mcu_swd; uint32_t sn_key; // 随机数 //uint32_t seed; // 芯片密钥,用于防止镜像文件复制到另一颗MCU上 //uint32_t chip_key[12]; // 如果值等于MAGIC_POWER_ON_RESTORE,恢复默认值(不包含动态参数) uint16_t RestoreParameter; // MAGIC_POWER_ON_RESTORE uint8_t cal_time; // 机器参数 DeviceParam_Type param; } NvmParam_Type; typedef struct { NvmParam_Type data; uint16_t sum[2]; } NvmData_Type; #pragma pack(pop) #define MAGIC_POWER_ON_RESTORE 0xA637 extern void drv_nvm_init(void); NvmParam_Type * drv_nvm_param_ptr(void); uint8_t drv_nvm_save_to_flash(void); void drv_nvm_load_default_calibration_value(NvmParam_Type * pData, uint8_t withDynamic); //void drv_nvm_load_default_calibration_dynamic_value(NvmParam_Type * pData); void drv_nvm_load_default_calibration_static_value(NvmParam_Type * pData, uint8_t reset_open_status);//gh,2024.1.3 reset_open_status是1就是恢复出厂设置,是0就是开机 uint8_t drv_nvm_get_param_value_by_id (uint8_t nvmId); #include "at32f403a_407_bpr.h" #include "at32f403a_407_crm.h" #include "at32f403a_407_pwc.h" static inline void drv_nvm_bpr_open(void) { crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_BPR_PERIPH_CLOCK, TRUE); pwc_battery_powered_domain_access(TRUE); while (PWC->ctrl_bit.bpwen == FALSE) { } } static inline void drv_nvm_arm_usb_boot(void) { drv_nvm_bpr_open(); BPR->dt1 = NVM_USB_BOOT_MAGIC; } static inline uint8_t drv_nvm_usb_boot_armed(void) { drv_nvm_bpr_open(); return ((BPR->dt1 & 0xFFFFu) == NVM_USB_BOOT_MAGIC) ? 1u : 0u; } static inline void drv_nvm_clear_usb_boot_arm(void) { drv_nvm_bpr_open(); BPR->dt1 = 0; } #endif // _DRV_NVM_H_