fmc_flash.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include "bsp.h"
  2. #if defined (GD32F30X_HD) || defined (GD32F30X_XD) || defined (GD32F30X_CL)
  3. #define FMC_FLAG_PGERR FMC_FLAG_BANK0_PGERR
  4. #define FMC_FLAG_PGAERR FMC_FLAG_BANK0_PGERR
  5. #define FMC_FLAG_WPERR FMC_FLAG_BANK0_WPERR
  6. #define FMC_FLAG_END FMC_FLAG_BANK0_END
  7. #endif
  8. #define one_page_size 2048
  9. #define data_bk_page_index 4
  10. #define data_page_index 3
  11. #define sn_page_index 2
  12. #define magic_page_index 1 //must is the last page in 256K eara
  13. static void _fmc_write_data(uint32_t addr, uint8_t *data, int len);
  14. static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
  15. static uint32_t _sn_addr(void);
  16. static uint32_t _data_addr(int index);
  17. static uint32_t _maigc_addr(void);
  18. void fmc_write_sn(uint8_t *sn, int len){
  19. _fmc_write_data(_sn_addr(), sn, len);
  20. }
  21. void fmc_read_sn(uint8_t *sn, int len){
  22. _fmc_read_data(_sn_addr(), sn, len);
  23. }
  24. void fmc_write_data(int index, uint8_t *data, int len){
  25. _fmc_write_data(_data_addr(index), data, len);
  26. }
  27. void fmc_read_data(int index, uint8_t *data, int len){
  28. _fmc_read_data(_data_addr(index), data, len);
  29. }
  30. static __inline__ void _fmc_flag_clear(void) {
  31. fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
  32. }
  33. void fmc_write_magic(uint32_t magic){
  34. uint32_t address = _maigc_addr();
  35. uint32_t length, checksum, value;
  36. value = REG32(address + 8);
  37. if (magic == value) {
  38. return;
  39. }
  40. length = REG32(address);
  41. checksum = REG32(address + 4);
  42. fmc_unlock();
  43. if (value != 0xFFFFFFFF) {
  44. _fmc_flag_clear();
  45. fmc_page_erase(address);
  46. _fmc_flag_clear();
  47. fmc_word_program(address, length);
  48. _fmc_flag_clear();
  49. fmc_word_program(address + 4, checksum);
  50. }
  51. if (magic != 0xFFFFFFFF) {
  52. _fmc_flag_clear();
  53. fmc_word_program(address + 8, magic);
  54. }
  55. fmc_lock();
  56. }
  57. uint32_t fmc_read_magic(void){
  58. uint32_t magic = 0x5555aaaa;
  59. _fmc_read_data(_maigc_addr(), (uint8_t *)&magic, sizeof(magic));
  60. return magic;
  61. }
  62. //if flash is lager than 256k, we just use the 256k
  63. static uint32_t __inline__ _flash_capatity(void){
  64. uint32_t capacity;
  65. capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
  66. if (capacity > (256 * 1024)){
  67. capacity = 256 * 1024;
  68. }
  69. return capacity;
  70. }
  71. static uint32_t _sn_addr(void){
  72. return 0x08000000 + (_flash_capatity() - one_page_size * sn_page_index);
  73. }
  74. static uint32_t _data_addr(int index){
  75. return 0x08000000 + (_flash_capatity() - one_page_size * (data_page_index + index));
  76. }
  77. static uint32_t _maigc_addr(void){
  78. return 0x08000000 + (_flash_capatity() - one_page_size * magic_page_index);
  79. }
  80. static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
  81. int i = 0;
  82. for (i = 0; i < len; i++){
  83. data[i] = REG8(addr + i);
  84. }
  85. }
  86. uint32_t fmc_get_addr(int page) {
  87. return 0x08000000 + (_flash_capatity() - one_page_size * page);
  88. }
  89. static void _fmc_write_data(uint32_t addr, uint8_t *data, int len){
  90. fmc_unlock();
  91. fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
  92. fmc_page_erase(addr);
  93. int total_words = len>>2;
  94. uint32_t *p_u32_data = (uint32_t *)data;
  95. int i;
  96. for (i = 0; i < total_words; i++){
  97. fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
  98. fmc_word_program(addr + i * 4, p_u32_data[i]);
  99. }
  100. data += i * 4;
  101. addr += i * 4;
  102. total_words = len - total_words * 4;
  103. if (total_words > 0){
  104. if (total_words == 1){
  105. uint16_t half = *data;
  106. fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
  107. fmc_halfword_program(addr, half);
  108. }else if (total_words == 2){
  109. uint16_t half = *((uint16_t *)data);
  110. fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
  111. fmc_halfword_program(addr, half);
  112. }else {
  113. uint32_t words = *((uint32_t *)data);
  114. fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END);
  115. fmc_word_program(addr, words);
  116. }
  117. }
  118. fmc_lock();
  119. }