| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- #include "gd32f3x0_libopt.h"
- #if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
- #define FMC_FLAG_PGERR FMC_FLAG_BANK0_PGERR
- #define FMC_FLAG_PGAERR FMC_FLAG_BANK0_PGERR
- #define FMC_FLAG_WPERR FMC_FLAG_BANK0_WPERR
- #define FMC_FLAG_END FMC_FLAG_BANK0_END
- #endif
- #define one_page_size 1024
- #define image_page_index 62
- #define sn_page_index 3
- #define data_page_index 2
- #define magic_page_index 1 //must is the last page in 256K eara
- static void _fmc_write_data(uint32_t addr, uint8_t *data, int len);
- static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
- static void _fmc_erase_addr(uint32_t addr, int len);
- static uint32_t _sn_addr(void);
- static uint32_t _data_addr(void);
- static uint32_t _maigc_addr(void);
- static uint32_t _image_addr(void);
- static uint32_t _image_write_addr = 0;
- static uint32_t _image_read_addr = 0;
- void fmc_write_sn(uint8_t *sn, int len){
- _fmc_erase_addr(_sn_addr(), len);
- _fmc_write_data(_sn_addr(), (uint8_t *)&len, sizeof(len));
- _fmc_write_data(_sn_addr() + sizeof(len), sn, len);
- }
- void fmc_read_sn(uint8_t *sn, int *len){
- int sn_len = 0;
- _fmc_read_data(_sn_addr(), (uint8_t *)&sn_len, sizeof(sn_len));
- if (sn_len > 0 && sn_len < *len) {
- _fmc_read_data(_sn_addr() + sizeof(sn_len), sn, sn_len);
- *len = sn_len;
- }
- *len = 0;
- }
- void fmc_write_data(uint8_t *data, int len){
- _fmc_erase_addr(_data_addr(), len);
- _fmc_write_data(_data_addr(), data, len);
- }
- void fmc_read_data(uint8_t *data, int len){
- _fmc_read_data(_data_addr(), data, len);
- }
- void fmc_erase_image(void){
- _fmc_erase_addr(_image_addr(), one_page_size * 50);
- _image_write_addr = 0;
- }
- void fmc_write_image(uint8_t *data, int len){
- _fmc_write_data(_image_addr() + _image_write_addr, data, len);
- _image_write_addr += len;
- }
- void fmc_start_read_image(void){
- _image_read_addr = 0;
- }
- void fmc_read_image(uint8_t *data, int len){
- _fmc_read_data(_image_addr() + _image_read_addr, data, len);
- _image_read_addr += len;
- }
- uint32_t fmc_iap_image_addr(void){
- return _image_addr();
- }
- void fmc_write_magic(uint32_t length, uint32_t checksum, uint32_t magic){
- uint32_t address = _maigc_addr();
- uint32_t buff[4];
- buff[0] = length;
- buff[1] = checksum;
- buff[2] = magic;
- buff[3] = _image_addr();
- _fmc_erase_addr(_maigc_addr(), sizeof(buff));
- _fmc_write_data(_maigc_addr(), (uint8_t *)buff ,sizeof(buff));
- }
- uint32_t fmc_read_magic(void){
- uint32_t magic = 0x5555aaaa;
- _fmc_read_data(_maigc_addr(), (uint8_t *)&magic, sizeof(magic));
- return magic;
- }
- //if flash is lager than 256k, we just use the 256k
- static uint32_t __inline__ _flash_capatity(void){
- uint32_t capacity;
- capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
- if (capacity > (256 * 1024)){
- capacity = 256 * 1024;
- }
- return capacity;
- }
- static uint32_t _sn_addr(void){
- return 0x08000000 + (_flash_capatity() - one_page_size * sn_page_index);
- }
- static uint32_t _data_addr(void){
- return 0x08000000 + (_flash_capatity() - one_page_size * data_page_index);
- }
- static uint32_t _maigc_addr(void){
- return 0x08000000 + (_flash_capatity() - one_page_size * magic_page_index);
- }
- static uint32_t _image_addr(void){
- return 0x08000000 + (one_page_size * image_page_index);
- }
- static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
- int i = 0;
- for (i = 0; i < len; i++){
- data[i] = REG8(addr + i);
- }
- }
- static void _fmc_erase_addr(uint32_t addr, int len){
- fmc_unlock();
- uint32_t pages = len/one_page_size + (((len % one_page_size) > 0)?1:0);
- for (int i = 0; i < pages; i++){
- fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
- fmc_page_erase(addr + i * one_page_size);
- }
- fmc_lock();
- }
- static void _fmc_write_data(uint32_t addr, uint8_t *data, int len){
- fmc_unlock();
- int total_words = len / 4;
- uint32_t *p_u32_data = (uint32_t *)data;
- int i;
- for (i = 0; i < total_words; i++){
- fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
- fmc_word_program(addr, p_u32_data[i]);
- data += 4;
- addr += 4;
- }
- int remain_len = len - total_words * 4;
- if (remain_len > 0){
- uint32_t words = 0;
- for (int i = 0; i < remain_len; i++){
- words |= data[i] << (8*i);
- }
- fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
- fmc_word_program(addr, words);
- }
- fmc_lock();
- }
|