FlashHelper.c
上传用户:yyyd609
上传日期:2022-07-18
资源大小:183k
文件大小:4k
源码类别:

微处理器开发

开发平台:

C/C++

  1. #include "FlashHelper.h"
  2. /* address offset of each sector in internal flash memory */
  3. static const struct flash_sector_info {
  4. u32 base, mask;
  5. } FlashSectorInfo[] = {
  6. {0x000000, FLASH_B0F0},
  7. {0x002000, FLASH_B0F1},
  8. {0x004000, FLASH_B0F2},
  9. {0x006000, FLASH_B0F3},
  10. {0x008000, FLASH_B0F4},
  11. {0x010000, FLASH_B0F5},
  12. {0x020000, FLASH_B0F6},
  13. {0x030000, FLASH_B0F7},
  14. {0x040000, ~0},
  15. {0x0C0000, FLASH_B1F0},
  16. {0x0C2000, FLASH_B1F1},
  17. {0x0C4000, ~0},
  18. {~0, ~0},
  19. };
  20. void Flash_Init(void)
  21. {
  22. FLASH_Init();
  23. }
  24. static void IntFlash_Wait(void)
  25. {
  26. while(FLASHR->CR0 & 0x16);
  27. }
  28. int IntFlash_Program(u32 addr, const void *buf, u32 size)
  29. {
  30. const struct flash_sector_info *p;
  31. u32 limit, mask;
  32. addr -= INT_FLASH_BASE;
  33. limit = addr + size;
  34. p = FlashSectorInfo;
  35. while(addr >= p[1].base)
  36. p++;
  37. mask = p->mask;
  38. while(limit > p[1].base)
  39. mask |= (++p)->mask;
  40. if(mask == ~0)
  41. return -1;
  42. IntFlash_Wait();
  43. FLASH_WritePrConfig(mask, DISABLE);
  44. IntFlash_Wait();
  45. FLASH_SectorErase(mask);
  46. IntFlash_Wait();
  47. FLASH_BlockWrite((u32)buf, addr, size + 3 >> 2);
  48. IntFlash_Wait();
  49. return 0;
  50. }
  51. #define FLASH_DATA(n) ( (n) >> 0  & 0x8000 /* D15 -> D15 */ 
  52. | (n) >> 1  & 0x2000 /* D14 -> D13 */ 
  53. | (n) >> 2  & 0x0800 /* D13 -> D11 */ 
  54. | (n) >> 3  & 0x0200 /* D12 -> D9  */ 
  55. | (n) >> 4  & 0x0080 /* D11 -> D7  */ 
  56. | (n) >> 5  & 0x0020 /* D10 -> D5  */ 
  57. | (n) >> 6  & 0x0008 /* D9  -> D3  */ 
  58. | (n) >> 7  & 0x0002 /* D8  -> D1  */ 
  59. | (n) << 7  & 0x4000 /* D7  -> D14 */ 
  60. | (n) << 6  & 0x1000 /* D6  -> D12 */ 
  61. | (n) << 5  & 0x0400 /* D5  -> D10 */ 
  62. | (n) << 4  & 0x0100 /* D4  -> D8  */ 
  63. | (n) << 3  & 0x0040 /* D3  -> D6  */ 
  64. | (n) << 2  & 0x0010 /* D2  -> D4  */ 
  65. | (n) << 1  & 0x0004 /* D1  -> D2  */ 
  66. | (n) << 0  & 0x0001 /* D0  -> D0  */ )
  67. #define FLASH_ADDR(a) ((vu16 *)(EXT_FLASH_BASE + ((a) << 1)))
  68. #define FLASH_WRITE(addr, word) (*FLASH_ADDR(addr) = FLASH_DATA(word))
  69. static void Check_Toggle_Ready(u32 addr)
  70. {
  71. int TimeOut;
  72. int PreData = *FLASH_ADDR(addr) & FLASH_DATA(0x0040);
  73. for(TimeOut = 0; TimeOut < 0x07FFFFFF; TimeOut++)
  74. {
  75. int CurData = *FLASH_ADDR(addr) & FLASH_DATA(0x0040);
  76. if(PreData == CurData)
  77. break;
  78. PreData = CurData;
  79. }
  80. }
  81. void ExtFlash_ChipErase(void)
  82. {
  83. FLASH_WRITE(0x5555, 0xaaaa);
  84. FLASH_WRITE(0x2aaa, 0x5555);
  85. FLASH_WRITE(0x5555, 0x8080);
  86. FLASH_WRITE(0x5555, 0xaaaa);
  87. FLASH_WRITE(0x2aaa, 0x5555);
  88. FLASH_WRITE(0x5555, 0x1010);
  89. Check_Toggle_Ready(0);
  90. }
  91. int ExtFlash_SectorErase(u32 addr)
  92. {
  93. addr = addr - EXT_FLASH_BASE >> 1;
  94. if(addr >= EXT_FLASH_SIZE)
  95. return -1;
  96. FLASH_WRITE(0x5555, 0xaaaa);
  97. FLASH_WRITE(0x2aaa, 0x5555);
  98. FLASH_WRITE(0x5555, 0x8080);
  99. FLASH_WRITE(0x5555, 0xaaaa);
  100. FLASH_WRITE(0x2aaa, 0x5555);
  101. FLASH_WRITE(addr, 0x3030);
  102. Check_Toggle_Ready(addr);
  103. return 0;
  104. }
  105. int ExtFlash_BlockErase(u32 addr)
  106. {
  107. addr = addr - EXT_FLASH_BASE >> 1;
  108. if(addr >= EXT_FLASH_SIZE)
  109. return -1;
  110. FLASH_WRITE(0x5555, 0xaaaa);
  111. FLASH_WRITE(0x2aaa, 0x5555);
  112. FLASH_WRITE(0x5555, 0x8080);
  113. FLASH_WRITE(0x5555, 0xaaaa);
  114. FLASH_WRITE(0x2aaa, 0x5555);
  115. FLASH_WRITE(addr, 0x5050);
  116. Check_Toggle_Ready(addr);
  117. return 0;
  118. }
  119. int ExtFlash_WordWrite(u32 addr, u16 data)
  120. {
  121. vu16 *ptr = (vu16 *)addr;
  122. addr = addr - EXT_FLASH_BASE >> 1;
  123. if(addr >= EXT_FLASH_SIZE)
  124. return -1;
  125. FLASH_WRITE(0x5555, 0xaaaa);
  126. FLASH_WRITE(0x2aaa, 0x5555);
  127. FLASH_WRITE(0x5555, 0xa0a0);
  128. *ptr = data;
  129. Check_Toggle_Ready(addr);
  130. return *ptr;
  131. }
  132. int ExtFlash_Program(u32 addr, const void *buf, u32 size)
  133. {
  134. u32 i, limit = addr + size;
  135. if(addr < EXT_FLASH_BASE || limit >= EXT_FLASH_LIMIT)
  136. return -1;
  137. for(i = addr & ~(SECTOR_SIZE - 1); i < limit; i += SECTOR_SIZE)
  138. ExtFlash_SectorErase(i);
  139. for(i = addr; i < limit; i += 2)
  140. {
  141. int PreData, TimeOut;
  142. FLASH_WRITE(0x5555, 0xaaaa);
  143. FLASH_WRITE(0x2aaa, 0x5555);
  144. FLASH_WRITE(0x5555, 0xa0a0);
  145. *(vu16 *)i = *(u16 *)buf;
  146. PreData = *(vu16 *)i & FLASH_DATA(0x0040);
  147. for(TimeOut = 0; TimeOut < 0x07FFFFFF; TimeOut++)
  148. {
  149. int CurData = *(vu16 *)i & FLASH_DATA(0x0040);
  150. if(PreData == CurData)
  151. break;
  152. PreData = CurData;
  153. }
  154. buf = (u16 *)buf + 1;
  155. }
  156. return 0;
  157. }