flash.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include "flash.h"
  2. /*******************************************************************************************************
  3. * @function: iap_flash_write_buf
  4. * @brief: 向iap flash区写入数据
  5. * @param: addr:数据偏移地址(基于IAP_FLASH_BASE_ADDR的偏移)
  6. * @param: buf:数据指针
  7. * @param: len:数据长度
  8. * @return: 实际写入的个数
  9. *******************************************************************************************************/
  10. uint16_t iap_flash_write_buf(uint32_t addr, uint8_t *buf, uint16_t len) {
  11. uint32_t hw_cnt;
  12. uint32_t i;
  13. uint16_t tmpData;
  14. uint32_t lenTmp = len;
  15. uint8_t offset = 0;
  16. FLASH_UnlockBank1(); // 解锁Flash
  17. if (addr % 2 != 0) {
  18. tmpData = *(__IO uint16_t*)(addr - 1);
  19. tmpData &= 0x00ff;
  20. tmpData += (((uint16_t)(*buf))<<8);
  21. FLASH_ProgramHalfWord(addr-1, tmpData);
  22. len -= 1;
  23. addr += 1;
  24. offset = 1;
  25. }
  26. hw_cnt = len / 2;
  27. for (i = 0; i < hw_cnt; i++) {
  28. FLASH_ProgramHalfWord(addr+i*2,*((uint16_t *)(buf+i*2+ offset)));
  29. }
  30. if (len%2!=0)
  31. {
  32. tmpData = buf[i*2];
  33. tmpData <<= 8;
  34. tmpData += (*(__IO uint16_t*)( addr+i*2))&0x00ff;
  35. FLASH_ProgramHalfWord( addr + i * 2, tmpData);
  36. }
  37. FLASH_LockBank1();
  38. return lenTmp;
  39. }
  40. ////读取指定地址的半字(16位数据)
  41. ////faddr:读地址(此地址必须为2的倍数!!)
  42. ////返回值:对应数据.
  43. u16 STMFLASH_ReadHalfWord(u32 faddr)
  44. {
  45. return *(vu16*)faddr;
  46. }
  47. //
  48. //
  49. //#if STM32_FLASH_WREN //如果使能了写
  50. ////不检查的写入
  51. ////WriteAddr:起始地址
  52. ////pBuffer:数据指针
  53. ////NumToWrite:半字(16位)数
  54. //void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
  55. //{
  56. // u16 i;
  57. // for(i=0;i<NumToWrite;i++)
  58. // {
  59. // FLASH_ProgramHalfWord(WriteAddr,pBuffer[i]);
  60. // WriteAddr+=2;//地址增加2.
  61. // }
  62. //}
  63. //
  64. ////从指定地址开始写入指定长度的数据
  65. ////WriteAddr:起始地址(此地址必须为2的倍数!!)
  66. ////pBuffer:数据指针
  67. ////NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
  68. //#if STM32_FLASH_SIZE<256
  69. //#define STM_SECTOR_SIZE 1024 //字节
  70. //#else
  71. //#define STM_SECTOR_SIZE 2048
  72. //#endif
  73. //
  74. //
  75. //u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];//最多是2K字节
  76. //void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
  77. //{
  78. // u32 secpos; //扇区地址
  79. // u16 secoff; //扇区内偏移地址(16位字计算)
  80. // u16 secremain; //扇区内剩余地址(16位字计算)
  81. // u16 i;
  82. // u32 offaddr; //去掉0X08000000后的地址
  83. // if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
  84. // FLASH_Unlock(); //解锁
  85. // offaddr=WriteAddr-STM32_FLASH_BASE; //实际偏移地址.
  86. // secpos=offaddr/STM_SECTOR_SIZE; //扇区地址 0~127 for STM32F103RBT6
  87. // secoff=(offaddr%STM_SECTOR_SIZE)/2; //在扇区内的偏移(2个字节为基本单位.)
  88. // secremain=STM_SECTOR_SIZE/2-secoff; //扇区剩余空间大小
  89. // if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
  90. // while(1)
  91. // {
  92. // STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
  93. // for(i=0;i<secremain;i++)//校验数据
  94. // {
  95. // if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除
  96. // }
  97. // if(i<secremain)//需要擦除
  98. // {
  99. // FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除这个扇区
  100. // for(i=0;i<secremain;i++)//复制
  101. // {
  102. // STMFLASH_BUF[i+secoff]=pBuffer[i];
  103. // }
  104. // STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区
  105. // }else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.
  106. // if(NumToWrite==secremain)break;//写入结束了
  107. // else//写入未结束
  108. // {
  109. // secpos++; //扇区地址增1
  110. // secoff=0; //偏移位置为0
  111. // pBuffer+=secremain; //指针偏移
  112. // WriteAddr+=secremain; //写地址偏移
  113. // NumToWrite-=secremain; //字节(16位)数递减
  114. // if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
  115. // else secremain=NumToWrite;//下一个扇区可以写完了
  116. // }
  117. // };
  118. // FLASH_Lock();//上锁
  119. //}
  120. //#endif
  121. //
  122. ////从指定地址开始读出指定长度的数据
  123. ////ReadAddr:起始地址
  124. ////pBuffer:数据指针
  125. ////NumToWrite:半字(16位)数
  126. void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
  127. {
  128. u16 i;
  129. for(i=0;i<NumToRead;i++)
  130. {
  131. pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
  132. ReadAddr+=2;//偏移2个字节.
  133. }
  134. }
  135. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  136. ////WriteAddr:起始地址
  137. ////WriteData:要写入的数据
  138. //void Test_Write(u32 WriteAddr,u16 WriteData)
  139. //{
  140. // STMFLASH_Write(WriteAddr,&WriteData,1);//写入一个字
  141. //}
  142. /**********************************************************************************************************
  143. *写页数据,擦除整页2048字节,并写入Byte数据,数据可少于2048Btye,但必须是偶数。//103CB 为1K 105RB 2K
  144. ************************************************************************************************************/
  145. char WritePageData(unsigned long WriteAddr,unsigned char *pData,unsigned short DataLen)
  146. {
  147. unsigned short i;
  148. unsigned short temp;
  149. FLASH_Status status;
  150. REWRITE:
  151. if(WriteAddr<STM32_FLASH_BASE || (WriteAddr>=(STM32_FLASH_BASE+1024*256)))return 1;//非法地址
  152. if(WriteAddr&0x0000003ff)return 2;//非页首地址
  153. FLASH_Unlock(); //解锁
  154. FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
  155. FLASH_WaitForLastBank1Operation(0xffffff);
  156. status=FLASH_ErasePage(WriteAddr);//擦除这个扇区
  157. if(status!=FLASH_COMPLETE){
  158. return 3;
  159. }
  160. FLASH_WaitForLastBank1Operation(0xffffff);
  161. //写入
  162. for(i = 0; i < DataLen; i+=2)
  163. {
  164. //数据8位融合为16位
  165. temp = (((unsigned short)pData[i+1])<<8) + ((unsigned short)pData[i]);
  166. status=FLASH_ProgramHalfWord((WriteAddr+i),temp);
  167. if(status!=4){
  168. printf("flash--statue===%d,%lu\r\n",status,WriteAddr);
  169. }
  170. }
  171. FLASH_Lock();//上锁
  172. return 0;
  173. }
  174. unsigned char FlashData[1024];
  175. /**********************************************************************************************************
  176. ************************************************************************************************************/
  177. void ReadFlashData(unsigned long ReadAddr,unsigned char *pData,unsigned short DataLen)
  178. {
  179. int i,j;
  180. unsigned short temp;
  181. j=0;
  182. for(i=0;i<DataLen;i+=2){
  183. temp=STMFLASH_ReadHalfWord(ReadAddr+i);
  184. pData[j++]=(unsigned char)(temp&0xff);
  185. pData[j++]=(temp>>8)&0xff;
  186. }
  187. }