Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

432 строки
12 KiB

  1. #include "SPI_Flash.h"
  2. #include "SPI.h"
  3. #include "BoardCfg.h"
  4. unsigned char mSPIFlashBaudrate;
  5. unsigned char mSPIFlashHighSpeedBaudrate;
  6. unsigned char mFlashSectorBuffer[SPI_FLASH_SECTOR_SIZE];
  7. unsigned int mSPIFlashOK;
  8. int InitSPIFlash()
  9. {
  10. FLASH_SS_PIN = 1;
  11. mSPIFlashBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, 25000000);
  12. // mSPIFlashHighSpeedBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, 50000000);
  13. mSPIFlashHighSpeedBaudrate = SPICalculateBRG(PERIPHERAL_FREQ, 35000000);
  14. mSPIFlashOK = 0;
  15. }
  16. int SPIFlashCheckAndConfigure()
  17. {
  18. if(SPIFlashCheckChipID() == RET_OK)
  19. {
  20. SPIFlashWriteEnable();
  21. FLASH_SS_PIN = 0;
  22. SPITransaction(SPI_FLASH_WRITE_STATUS_REG,mSPIFlashHighSpeedBaudrate);
  23. SPITransaction(0x00,mSPIFlashHighSpeedBaudrate); //Configure for write enable the whole memory
  24. FLASH_SS_PIN = 1;
  25. SPIFlashReadStatusReg(1);
  26. mSPIFlashOK = 1;
  27. printf("SPI Flash configured\n");
  28. return RET_OK;
  29. }
  30. mSPIFlashOK = 0;
  31. printf("ERROR: SPI Flash not detected\n");
  32. return RET_ERROR;
  33. }
  34. int SPIFlashIsPresent()
  35. {
  36. return mSPIFlashOK;
  37. }
  38. int SPIFlashWriteEnable()
  39. {
  40. FLASH_SS_PIN = 0;
  41. SPITransaction(SPI_FLASH_WRITE_ENABLE,mSPIFlashHighSpeedBaudrate);
  42. FLASH_SS_PIN = 1;
  43. return RET_OK;
  44. }
  45. unsigned char SPIFlashReadStatusReg(int print)
  46. {
  47. unsigned char result;
  48. FLASH_SS_PIN = 0;
  49. result = SPITransaction(SPI_FLASH_READ_STATUS_REG,mSPIFlashBaudrate);
  50. result = SPITransaction(0x00,mSPIFlashBaudrate); //get data
  51. FLASH_SS_PIN = 1;
  52. if(print)
  53. {
  54. printf("Flash status register : 0x%x\n",result);
  55. }
  56. return result;
  57. }
  58. int SPIFlashCheckBusy()
  59. {
  60. unsigned char status = SPIFlashReadStatusReg(0);
  61. if((status & SPI_FLASH_BUSY_MASK) != 0)
  62. {
  63. return 1;
  64. }
  65. return 0;
  66. }
  67. int SPIFlashCheckChipID()
  68. {
  69. unsigned char VendorID, ChipID;
  70. FLASH_SS_PIN = 0;
  71. SPITransaction(SPI_FLASH_READ_ID,mSPIFlashBaudrate);
  72. SPITransaction(0x00,mSPIFlashBaudrate);
  73. SPITransaction(0x00,mSPIFlashBaudrate);
  74. SPITransaction(0x00,mSPIFlashBaudrate); //Vendor address
  75. VendorID = SPITransaction(0x00,mSPIFlashBaudrate); //Vendor ID, should be 0xBF
  76. ChipID = SPITransaction(0x00,mSPIFlashBaudrate); //Device ID, should be 0x41
  77. FLASH_SS_PIN = 1;
  78. if(VendorID != SPI_FLASH_VENDOR_ID || ChipID != SPI_FLASH_CHIP_ID)
  79. {
  80. printf("SPI Flash detection FAILED. Vendor: 0x%x, Chip ID: 0x%x\n",VendorID,ChipID);
  81. return RET_ERROR;
  82. }
  83. printf("SPI Flash detected. Vendor: 0x%x, Chip ID: 0x%x\n",VendorID,ChipID);
  84. return RET_OK;
  85. }
  86. int SPIFlashReadBuffer(unsigned char *Buf, int Size, int StartAddress)
  87. {
  88. if(StartAddress + Size - 1 > SPI_FLASH_MAX_ADDRESS)
  89. {
  90. return RET_ERROR;
  91. }
  92. FLASH_SS_PIN = 0;
  93. SPITransaction(SPI_FLASH_HI_SPEED_READ,mSPIFlashBaudrate);
  94. SPITransaction(((StartAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
  95. SPITransaction(((StartAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
  96. SPITransaction((StartAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
  97. SPITransaction((0x00),mSPIFlashHighSpeedBaudrate); //Chip requires a dummy read in high speed
  98. int i;
  99. for(i = 0; i < Size; i++)
  100. {
  101. unsigned char tmp;
  102. tmp =SPITransaction(0xDE,mSPIFlashHighSpeedBaudrate);
  103. *Buf++ = tmp;
  104. // *Buf++ = SPITransaction(0xDE,mSPIFlashHighSpeedBaudrate);
  105. }
  106. FLASH_SS_PIN = 1;
  107. return RET_OK;
  108. }
  109. int SPIFlashEraseSector(int SectorAddress)
  110. {
  111. if(SectorAddress % SPI_FLASH_SECTOR_SIZE != 0) //Sectors are aligned on 0x1000
  112. {
  113. return RET_ERROR;
  114. }
  115. SPIFlashWriteEnable();
  116. FLASH_SS_PIN = 0;
  117. SPITransaction(SPI_FLASH_4KB_SECOTR_ERASE,mSPIFlashHighSpeedBaudrate);
  118. SPITransaction(((SectorAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
  119. SPITransaction(((SectorAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
  120. SPITransaction((SectorAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
  121. FLASH_SS_PIN = 1;
  122. SectorAddress++;
  123. while( SPIFlashCheckBusy() == true);
  124. //SPIFlashWriteEnable();
  125. return RET_OK;
  126. }
  127. int SPIFlashErase64KSector(int SectorAddress, int Blocking)
  128. {
  129. if(SectorAddress % SPI_FLASH_64K_SECTOR_SIZE != 0) //Sectors are aligned on 0x1000
  130. {
  131. return RET_ERROR;
  132. }
  133. if((SectorAddress + SPI_FLASH_64K_SECTOR_SIZE - 1) > SPI_FLASH_MAX_ADDRESS)
  134. {
  135. return RET_ERROR;
  136. }
  137. SPIFlashWriteEnable();
  138. FLASH_SS_PIN = 0;
  139. SPITransaction(SPI_FLASH_64KB_BLOCK_ERASE,mSPIFlashHighSpeedBaudrate);
  140. SPITransaction(((SectorAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
  141. SPITransaction(((SectorAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
  142. SPITransaction((SectorAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
  143. FLASH_SS_PIN = 1;
  144. if(Blocking != 0)
  145. {
  146. while( SPIFlashCheckBusy() == true);
  147. // SPIFlashWriteEnable();
  148. }
  149. return RET_OK;
  150. }
  151. int SPIFlashWriteSectorWorkingBuffer(int SectorAddress, int Erase)
  152. {
  153. if(SectorAddress % SPI_FLASH_SECTOR_SIZE != 0) //Sectors are aligned on 0x1000
  154. {
  155. return RET_ERROR;
  156. }
  157. if(Erase == 1)
  158. {
  159. SPIFlashEraseSector(SectorAddress);
  160. }
  161. unsigned char *DataPtr = &mFlashSectorBuffer[0];
  162. int j;
  163. for(j = 0; j < SPI_FLASH_SECTOR_SIZE; j++)
  164. {
  165. unsigned char curbyte;
  166. curbyte = *DataPtr;
  167. SPIFlashWriteEnable();
  168. char Add1, Add2, Add3;
  169. Add1 = (unsigned char)((SectorAddress & 0xFF0000) >> 16);
  170. Add2 = ((unsigned char)((SectorAddress & 0x00FF00) >> 8));
  171. Add3 = ((unsigned char)(SectorAddress & 0x0000FF));
  172. int t;
  173. t = 0;
  174. FLASH_SS_PIN = 0;
  175. SPITransaction(SPI_FLASH_BYTE_PROGRAM,mSPIFlashHighSpeedBaudrate);
  176. // SPITransaction((unsigned char)((SectorAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
  177. // SPITransaction((unsigned char)((SectorAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
  178. // SPITransaction((unsigned char)(SectorAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
  179. SPITransaction(Add1,mSPIFlashHighSpeedBaudrate);
  180. SPITransaction(Add2,mSPIFlashHighSpeedBaudrate);
  181. SPITransaction(Add3,mSPIFlashHighSpeedBaudrate);
  182. SPITransaction(curbyte,mSPIFlashHighSpeedBaudrate);
  183. // SPITransaction(*DataPtr,mSPIFlashHighSpeedBaudrate);
  184. FLASH_SS_PIN = 1;
  185. DataPtr++;
  186. SectorAddress++;
  187. while( SPIFlashCheckBusy() == true);
  188. }
  189. return RET_OK;
  190. }
  191. int SPIFlashWriteByte(unsigned int ByteAddress, char byte, int blocking)
  192. {
  193. if(ByteAddress > SPI_FLASH_MAX_ADDRESS)
  194. {
  195. return RET_ERROR;
  196. }
  197. SPIFlashWriteEnable();
  198. FLASH_SS_PIN = 0;
  199. SPITransaction(SPI_FLASH_BYTE_PROGRAM,mSPIFlashHighSpeedBaudrate);
  200. SPITransaction(((ByteAddress & 0xFF0000) >> 16),mSPIFlashHighSpeedBaudrate);
  201. SPITransaction(((ByteAddress & 0x00FF00) >> 8),mSPIFlashHighSpeedBaudrate);
  202. SPITransaction((ByteAddress & 0x0000FF),mSPIFlashHighSpeedBaudrate);
  203. SPITransaction(byte,mSPIFlashHighSpeedBaudrate);
  204. FLASH_SS_PIN = 1;
  205. if(blocking)
  206. {
  207. while( SPIFlashCheckBusy() == true);
  208. }
  209. return RET_OK;
  210. }
  211. //int SPIFlashEraseSectorForWrite(unsigned char StartAddress, int Size)
  212. //{
  213. // //First, let's determine which sector to erase.
  214. //
  215. // int NbSectors = 1;
  216. // int FirstSector = StartAddress / 0x1000;
  217. // int LastSector = (StartAddress + Size) / 0x1000;
  218. //
  219. // if(LastSector > FirstSector)
  220. // {
  221. // NbSectors = LastSector - FirstSector;
  222. // }
  223. //
  224. // int i;
  225. // for(i = FirstSector; i < LastSector; i++ ) //Erase each sector one by one
  226. // {
  227. //
  228. // }
  229. //
  230. //}
  231. //int SPIFlashWriteBuffer(unsigned char *Buf, int Size, int StartAddress)
  232. //{
  233. // //First, we need to determine if the data overlaps or uses more than one sector
  234. // //First, let's determine which sector to erase.
  235. // int EndAddress = StartAddress + Size - 1;
  236. // if(EndAddress > SPI_FLASH_MAX_ADDRESS)
  237. // {
  238. // return RET_ERROR;
  239. // }
  240. //
  241. // int NbSectors = 1;
  242. // int FirstSector = StartAddress / SPI_FLASH_SECTOR_SIZE;
  243. // int LastSector = EndAddress / SPI_FLASH_SECTOR_SIZE;
  244. //
  245. // if(LastSector > FirstSector)
  246. // {
  247. // NbSectors = LastSector - FirstSector + 1;
  248. // }
  249. //
  250. // int i;
  251. // int FlashAddress = StartAddress;
  252. // int CurSector = FirstSector;
  253. // for(i = 0; i < NbSectors; i++ ) //Read, erase and write each sector one by one
  254. // {
  255. // //first we need to backup the data outside our buffer.
  256. // //TODO: optimize
  257. // int SectorStartAddress = CurSector++ * SPI_FLASH_SECTOR_SIZE;
  258. // int SectorEndAddress = SectorStartAddress + SPI_FLASH_SECTOR_SIZE - 1;
  259. // if(SectorEndAddress > EndAddress)
  260. // {
  261. // SectorEndAddress = EndAddress;
  262. // }
  263. //
  264. // SPIFlashReadBuffer(mFlashSectorBuffer,SPI_FLASH_SECTOR_SIZE,SectorStartAddress); //Get local RAM buffer of the sector
  265. //
  266. // //Update the data to write.
  267. // int RAMAddress = FlashAddress - SectorStartAddress;
  268. // int RAMSectorSize = SectorEndAddress - FlashAddress + 1;
  269. // FlashAddress += RAMSectorSize;
  270. //
  271. // unsigned char* RAMPtr = &mFlashSectorBuffer[RAMAddress];
  272. // int j;
  273. // for(j = 0; j < RAMSectorSize; j++)
  274. // {
  275. // *RAMPtr++ = *Buf++;
  276. // }
  277. //
  278. // int SectorAddress = SectorStartAddress;
  279. // RAMPtr = mFlashSectorBuffer;
  280. //
  281. // for(j = 0; j < SPI_FLASH_SECTOR_SIZE; j++)
  282. // {
  283. // SPIFlashWriteEnable();
  284. //
  285. // FLASH_SS_PIN = 0;
  286. // SPITransaction(SPI_FLASH_BYTE_PROGRAM,mSPIFlashHighSpeedBaudrate);
  287. // SPITransaction(((SectorAddress & 0xFF0000) >> 16),mSPIFlashBaudrate);
  288. // SPITransaction(((SectorAddress & 0x00FF00) >> 8),mSPIFlashBaudrate);
  289. // SPITransaction((SectorAddress & 0x0000FF),mSPIFlashBaudrate);
  290. // SPITransaction(*RAMPtr++,mSPIFlashBaudrate);
  291. // FLASH_SS_PIN = 1;
  292. //
  293. // SectorAddress++;
  294. //
  295. // while( SPIFlashCheckBusy() == true);
  296. // }
  297. // }
  298. //}
  299. int SPIFlashWriteBuffer(unsigned char *Buf, int Size, int StartAddress)
  300. {
  301. int CurDataFlashAddress, DataFlashEndAddress;
  302. char *DataBufPtr, *WorkPagePtr;
  303. int WriteFinished;
  304. //Init stuff
  305. WriteFinished = 0;
  306. DataFlashEndAddress = StartAddress + Size; //Start + size means the data at "DataFlashEndAddress" should not be written.
  307. CurDataFlashAddress = StartAddress;
  308. DataBufPtr = Buf;
  309. if(DataFlashEndAddress > SPI_FLASH_MAX_ADDRESS)
  310. {
  311. return RET_ERROR;
  312. }
  313. while(WriteFinished == 0)
  314. {
  315. //Determine the current sector start address.
  316. int SectorStartAddress;
  317. SectorStartAddress = ((CurDataFlashAddress / SPI_FLASH_SECTOR_SIZE) * SPI_FLASH_SECTOR_SIZE); //Weird but it works
  318. //Load the sector in RAM working buffer
  319. if(SPIFlashReadBuffer(mFlashSectorBuffer,SPI_FLASH_SECTOR_SIZE,SectorStartAddress) != RET_OK)
  320. {
  321. return RET_ERROR;
  322. }
  323. //Set the working buffer pointer to the right value.
  324. WorkPagePtr = &mFlashSectorBuffer[CurDataFlashAddress - SectorStartAddress];
  325. //Modify the working buffer with data to write.
  326. int SectorFinished = 0;
  327. while(SectorFinished == 0)
  328. {
  329. *WorkPagePtr++ = *DataBufPtr++;
  330. CurDataFlashAddress++;
  331. //Are we at the end of the buffer to write?
  332. if(CurDataFlashAddress == DataFlashEndAddress)
  333. {
  334. SectorFinished = 1;
  335. WriteFinished = 1;
  336. // SPIFlashEraseSector(SectorStartAddress);
  337. SPIFlashWriteSectorWorkingBuffer(SectorStartAddress,1);
  338. break;
  339. }
  340. else if(CurDataFlashAddress % SPI_FLASH_SECTOR_SIZE == 0) //Are we at the beginning of the next sector?
  341. {
  342. SectorFinished = 1;
  343. // SPIFlashEraseSector(SectorStartAddress);
  344. SPIFlashWriteSectorWorkingBuffer(SectorStartAddress,1);
  345. break;
  346. }
  347. }
  348. }
  349. return 1;
  350. }