fmc_flash.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include "bsp/bsp_driver.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. static void _fmc_write_data(uint32_t addr, uint8_t *data, int len);
  9. static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
  10. static void _fmc_erase_addr(uint32_t addr, int len);
  11. static void _fmc_read_data(uint32_t addr, uint8_t *data, int len);
  12. static void _fmc_erase_write_data(uint32_t addr, uint8_t *data, int len);
  13. static uint32_t _sn_addr(void);
  14. static uint32_t _data_addr(int index);
  15. static uint32_t _maigc_addr(void);
  16. void fmc_write_sn(uint8_t *sn, int len){
  17. _fmc_erase_write_data(_sn_addr(), sn, len);
  18. }
  19. void fmc_read_sn(uint8_t *sn, int len){
  20. _fmc_read_data(_sn_addr(), sn, len);
  21. }
  22. void fmc_write_data(int index, uint8_t *data, int len){
  23. _fmc_erase_write_data(_data_addr(index), data, len);
  24. }
  25. void fmc_read_data(int index, uint8_t *data, int len){
  26. _fmc_read_data(_data_addr(index), data, len);
  27. }
  28. static __inline__ void _fmc_flag_clear(void) {
  29. flash_flag_clear(FLASH_OBF_FLAG | FLASH_ODF_FLAG | FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
  30. }
  31. void fmc_write_magic(uint32_t magic){
  32. uint32_t address = _maigc_addr();
  33. uint32_t length, checksum, value;
  34. value = REG32(address + 8);
  35. if (magic == value) {
  36. return;
  37. }
  38. length = REG32(address);
  39. checksum = REG32(address + 4);
  40. flash_unlock();
  41. if (value != 0xFFFFFFFF) {
  42. _fmc_flag_clear();
  43. flash_sector_erase(address);
  44. _fmc_flag_clear();
  45. flash_word_program(address, length);
  46. _fmc_flag_clear();
  47. flash_word_program(address + 4, checksum);
  48. }
  49. if (magic != 0xFFFFFFFF) {
  50. _fmc_flag_clear();
  51. flash_word_program(address + 8, magic);
  52. }
  53. flash_lock();
  54. }
  55. uint32_t fmc_read_magic(void){
  56. uint32_t magic = 0x5555aaaa;
  57. _fmc_read_data(_maigc_addr(), (uint8_t *)&magic, sizeof(magic));
  58. return magic;
  59. }
  60. //if flash is lager than 256k, we just use the 256k
  61. static uint32_t __inline__ _flash_capatity(void){
  62. uint32_t capacity;
  63. capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
  64. if (capacity > (256 * 1024)){
  65. capacity = 256 * 1024;
  66. }
  67. return capacity;
  68. }
  69. static uint32_t _sn_addr(void){
  70. return 0x08000000 + (_flash_capatity() - one_page_size * sn_page_index);
  71. }
  72. static uint32_t _data_addr(int index){
  73. return 0x08000000 + (_flash_capatity() - one_page_size * index);
  74. }
  75. static uint32_t _maigc_addr(void){
  76. return 0x08000000 + (_flash_capatity() - one_page_size * magic_page_index);
  77. }
  78. static void _fmc_read_data(uint32_t addr, uint8_t *data, int len){
  79. int i = 0;
  80. for (i = 0; i < len; i++){
  81. data[i] = REG8(addr + i);
  82. }
  83. }
  84. uint32_t fmc_get_addr(int page) {
  85. return 0x08000000 + (_flash_capatity() - one_page_size * page);
  86. }
  87. extern void wdog_reload(void);
  88. static void _fmc_erase_addr(uint32_t addr, int len){
  89. flash_unlock();
  90. uint32_t pages = len/one_page_size + (((len % one_page_size) > 0)?1:0);
  91. for (int i = 0; i < pages; i++){
  92. _fmc_flag_clear();
  93. flash_sector_erase(addr + i * one_page_size);
  94. wdog_reload();
  95. }
  96. flash_lock();
  97. }
  98. static void _fmc_write_data(uint32_t addr, uint8_t *data, int len){
  99. flash_unlock();
  100. int total_words = len / 4;
  101. uint32_t *p_u32_data = (uint32_t *)data;
  102. int i;
  103. for (i = 0; i < total_words; i++){
  104. _fmc_flag_clear();
  105. flash_word_program(addr, p_u32_data[i]);
  106. data += 4;
  107. addr += 4;
  108. }
  109. int remain_len = len - total_words * 4;
  110. if (remain_len > 0){
  111. uint32_t words = 0;
  112. for (int i = 0; i < remain_len; i++){
  113. words |= data[i] << (8*i);
  114. }
  115. _fmc_flag_clear();
  116. flash_word_program(addr, words);
  117. }
  118. flash_lock();
  119. }
  120. static void _fmc_erase_write_data(uint32_t addr, uint8_t *data, int len){
  121. _fmc_erase_addr(addr, len);
  122. _fmc_write_data(addr, data, len);
  123. }