at45.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /*----------------------------------------------------------------------------
  2. * ATMEL Microcontroller Software Support - ROUSSET -
  3. *----------------------------------------------------------------------------
  4. * The software is delivered "AS IS" without warranty or condition of any
  5. * kind, either express, implied or statutory. This includes without
  6. * limitation any warranty or condition with respect to merchantability or
  7. * fitness for any particular purpose, or against the infringements of
  8. * intellectual property rights of others.
  9. *----------------------------------------------------------------------------
  10. * File Name : at45c.h
  11. * Object :
  12. *
  13. * 1.0 10/12/03 HIi : Creation.
  14. * 1.01 03/05/04 HIi : Bug Fix in AT91F_DataFlashWaitReady() Function.
  15. *----------------------------------------------------------------------------
  16. */
  17. #include "config.h"
  18. #include "stdio.h"
  19. #include "AT91RM9200.h"
  20. #include "lib_AT91RM9200.h"
  21. #include "dataflash.h"
  22. #include "main.h"
  23. /*----------------------------------------------------------------------------*/
  24. /* \fn AT91F_SpiInit */
  25. /* \brief SPI Low level Init */
  26. /*----------------------------------------------------------------------------*/
  27. void AT91F_SpiInit(void) {
  28. /* Configure PIOs */
  29. AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 |
  30. AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
  31. AT91C_PA6_NPCS3 | AT91C_PA0_MISO |
  32. AT91C_PA2_SPCK;
  33. AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 |
  34. AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
  35. AT91C_PA6_NPCS3 | AT91C_PA0_MISO |
  36. AT91C_PA2_SPCK;
  37. /* Enable CLock */
  38. AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
  39. /* Reset the SPI */
  40. AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
  41. /* Configure SPI in Master Mode with No CS selected !!! */
  42. AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
  43. /* Configure CS0 and CS3 */
  44. *(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) |
  45. (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) |
  46. ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
  47. *(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) |
  48. (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) |
  49. ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
  50. }
  51. /*----------------------------------------------------------------------------*/
  52. /* \fn AT91F_SpiEnable */
  53. /* \brief Enable SPI chip select */
  54. /*----------------------------------------------------------------------------*/
  55. static void AT91F_SpiEnable(int cs) {
  56. switch(cs) {
  57. case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
  58. AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
  59. AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH << 16) & AT91C_SPI_PCS);
  60. break;
  61. case 3: /* Configure SPI CS3 for Serial DataFlash Card */
  62. /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
  63. AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */
  64. AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */
  65. /* Clear Output */
  66. AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
  67. /* Configure PCS */
  68. AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
  69. AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
  70. break;
  71. }
  72. /* SPI_Enable */
  73. AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
  74. }
  75. /*----------------------------------------------------------------------------*/
  76. /* \fn AT91F_SpiWrite */
  77. /* \brief Set the PDC registers for a transfert */
  78. /*----------------------------------------------------------------------------*/
  79. static unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc)
  80. {
  81. unsigned int timeout;
  82. AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
  83. /* Initialize the Transmit and Receive Pointer */
  84. AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
  85. AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
  86. /* Intialize the Transmit and Receive Counters */
  87. AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
  88. AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
  89. if ( pDesc->tx_data_size != 0 ) {
  90. /* Initialize the Next Transmit and Next Receive Pointer */
  91. AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
  92. AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
  93. /* Intialize the Next Transmit and Next Receive Counters */
  94. AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
  95. AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
  96. }
  97. /* ARM simple, non interrupt dependent timer */
  98. timeout = 0;
  99. AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
  100. while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF));
  101. AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
  102. if (timeout >= AT91C_DATAFLASH_TIMEOUT){
  103. return AT91C_DATAFLASH_ERROR;
  104. }
  105. return AT91C_DATAFLASH_OK;
  106. }
  107. /*----------------------------------------------------------------------*/
  108. /* \fn AT91F_DataFlashSendCommand */
  109. /* \brief Generic function to send a command to the dataflash */
  110. /*----------------------------------------------------------------------*/
  111. static AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
  112. AT91PS_DataFlash pDataFlash,
  113. unsigned char OpCode,
  114. unsigned int CmdSize,
  115. unsigned int DataflashAddress)
  116. {
  117. unsigned int adr;
  118. /* process the address to obtain page address and byte address */
  119. adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size))
  120. << pDataFlash->pDevice->page_offset) +
  121. (DataflashAddress % (pDataFlash->pDevice->pages_size));
  122. /* fill the command buffer */
  123. pDataFlash->pDataFlashDesc->command[0] = OpCode;
  124. if (pDataFlash->pDevice->pages_number >= 16384)
  125. {
  126. pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24);
  127. pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16);
  128. pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8);
  129. pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF);
  130. }
  131. else
  132. {
  133. pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
  134. pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
  135. pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
  136. pDataFlash->pDataFlashDesc->command[4] = 0;
  137. }
  138. pDataFlash->pDataFlashDesc->command[5] = 0;
  139. pDataFlash->pDataFlashDesc->command[6] = 0;
  140. pDataFlash->pDataFlashDesc->command[7] = 0;
  141. /* Initialize the SpiData structure for the spi write fuction */
  142. pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
  143. pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ;
  144. pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
  145. pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ;
  146. return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
  147. }
  148. /*----------------------------------------------------------------------*/
  149. /* \fn AT91F_DataFlashGetStatus */
  150. /* \brief Read the status register of the dataflash */
  151. /*----------------------------------------------------------------------*/
  152. static AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
  153. {
  154. AT91S_DataFlashStatus status;
  155. /* first send the read status command (D7H) */
  156. pDesc->command[0] = DB_STATUS;
  157. pDesc->command[1] = 0;
  158. pDesc->DataFlash_state = GET_STATUS;
  159. pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */
  160. pDesc->tx_cmd_pt = pDesc->command ;
  161. pDesc->rx_cmd_pt = pDesc->command ;
  162. pDesc->rx_cmd_size = 2 ;
  163. pDesc->tx_cmd_size = 2 ;
  164. status = AT91F_SpiWrite (pDesc);
  165. pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
  166. return status;
  167. }
  168. /*-----------------------------------------------------------------------------
  169. * Function Name : AT91F_DataFlashWaitReady
  170. * Object : wait for dataflash ready (bit7 of the status register == 1)
  171. * Input Parameters : DataFlash Service and timeout
  172. * Return value : DataFlash status "ready or not"
  173. *-----------------------------------------------------------------------------
  174. */
  175. static AT91S_DataFlashStatus AT91F_DataFlashWaitReady(
  176. AT91PS_DataflashDesc pDataFlashDesc,
  177. unsigned int timeout)
  178. {
  179. pDataFlashDesc->DataFlash_state = IDLE;
  180. do {
  181. AT91F_DataFlashGetStatus(pDataFlashDesc);
  182. timeout--;
  183. }
  184. while(((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0));
  185. if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
  186. return AT91C_DATAFLASH_ERROR;
  187. return AT91C_DATAFLASH_OK;
  188. }
  189. /*------------------------------------------------------------------------------*/
  190. /* Function Name : AT91F_DataFlashContinuousRead */
  191. /* Object : Continuous stream Read */
  192. /* Input Parameters : DataFlash Service */
  193. /* : <src> = dataflash address */
  194. /* : <*dataBuffer> = data buffer pointer */
  195. /* : <sizeToRead> = data buffer size */
  196. /* Return value : State of the dataflash */
  197. /*------------------------------------------------------------------------------*/
  198. static AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(
  199. AT91PS_DataFlash pDataFlash,
  200. int src,
  201. unsigned char *dataBuffer,
  202. int sizeToRead )
  203. {
  204. AT91S_DataFlashStatus status;
  205. /* Test the size to read in the device */
  206. if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
  207. return AT91C_DATAFLASH_MEMORY_OVERFLOW;
  208. pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
  209. pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
  210. pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
  211. pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
  212. status = AT91F_DataFlashSendCommand(pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
  213. /* Send the command to the dataflash */
  214. return(status);
  215. }
  216. /*------------------------------------------------------------------------------*/
  217. /* Function Name : AT91F_MainMemoryToBufferTransfer */
  218. /* Object : Read a page in the SRAM Buffer 1 or 2 */
  219. /* Input Parameters : DataFlash Service */
  220. /* : Page concerned */
  221. /* : */
  222. /* Return value : State of the dataflash */
  223. /*------------------------------------------------------------------------------*/
  224. static AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfer(
  225. AT91PS_DataFlash pDataFlash,
  226. unsigned char BufferCommand,
  227. unsigned int page)
  228. {
  229. int cmdsize;
  230. /* Test if the buffer command is legal */
  231. if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
  232. return AT91C_DATAFLASH_BAD_COMMAND;
  233. /* no data to transmit or receive */
  234. pDataFlash->pDataFlashDesc->tx_data_size = 0;
  235. cmdsize = 4;
  236. if (pDataFlash->pDevice->pages_number >= 16384)
  237. cmdsize = 5;
  238. return(AT91F_DataFlashSendCommand(pDataFlash, BufferCommand, cmdsize,
  239. page*pDataFlash->pDevice->pages_size));
  240. }
  241. /*----------------------------------------------------------------------------- */
  242. /* Function Name : AT91F_DataFlashWriteBuffer */
  243. /* Object : Write data to the internal sram buffer 1 or 2 */
  244. /* Input Parameters : DataFlash Service */
  245. /* : <BufferCommand> = command to write buffer1 or buffer2 */
  246. /* : <*dataBuffer> = data buffer to write */
  247. /* : <bufferAddress> = address in the internal buffer */
  248. /* : <SizeToWrite> = data buffer size */
  249. /* Return value : State of the dataflash */
  250. /*------------------------------------------------------------------------------*/
  251. static AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(
  252. AT91PS_DataFlash pDataFlash,
  253. unsigned char BufferCommand,
  254. unsigned char *dataBuffer,
  255. unsigned int bufferAddress,
  256. int SizeToWrite )
  257. {
  258. int cmdsize;
  259. /* Test if the buffer command is legal */
  260. if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
  261. return AT91C_DATAFLASH_BAD_COMMAND;
  262. /* buffer address must be lower than page size */
  263. if (bufferAddress > pDataFlash->pDevice->pages_size)
  264. return AT91C_DATAFLASH_BAD_ADDRESS;
  265. /* Send first Write Command */
  266. pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
  267. pDataFlash->pDataFlashDesc->command[1] = 0;
  268. if (pDataFlash->pDevice->pages_number >= 16384)
  269. {
  270. pDataFlash->pDataFlashDesc->command[2] = 0;
  271. pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
  272. pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
  273. cmdsize = 5;
  274. }
  275. else
  276. {
  277. pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
  278. pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
  279. pDataFlash->pDataFlashDesc->command[4] = 0;
  280. cmdsize = 4;
  281. }
  282. pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
  283. pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ;
  284. pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
  285. pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ;
  286. pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;
  287. pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
  288. pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ;
  289. pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
  290. return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
  291. }
  292. /*------------------------------------------------------------------------------*/
  293. /* Function Name : AT91F_PageErase */
  294. /* Object : Read a page in the SRAM Buffer 1 or 2 */
  295. /* Input Parameters : DataFlash Service */
  296. /* : Page concerned */
  297. /* : */
  298. /* Return value : State of the dataflash */
  299. /*------------------------------------------------------------------------------*/
  300. static AT91S_DataFlashStatus AT91F_PageErase(
  301. AT91PS_DataFlash pDataFlash,
  302. unsigned int page)
  303. {
  304. int cmdsize;
  305. /* Test if the buffer command is legal */
  306. /* no data to transmit or receive */
  307. pDataFlash->pDataFlashDesc->tx_data_size = 0;
  308. cmdsize = 4;
  309. if (pDataFlash->pDevice->pages_number >= 16384)
  310. cmdsize = 5;
  311. return(AT91F_DataFlashSendCommand(pDataFlash, DB_PAGE_ERASE, cmdsize,
  312. page*pDataFlash->pDevice->pages_size));
  313. }
  314. /*------------------------------------------------------------------------------*/
  315. /* Function Name : AT91F_WriteBufferToMain */
  316. /* Object : Write buffer to the main memory */
  317. /* Input Parameters : DataFlash Service */
  318. /* : <BufferCommand> = command to send to buf1 or buf2 */
  319. /* : <dest> = main memory address */
  320. /* Return value : State of the dataflash */
  321. /*------------------------------------------------------------------------------*/
  322. static AT91S_DataFlashStatus AT91F_WriteBufferToMain (
  323. AT91PS_DataFlash pDataFlash,
  324. unsigned char BufferCommand,
  325. unsigned int dest )
  326. {
  327. int cmdsize;
  328. /* Test if the buffer command is correct */
  329. if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
  330. (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
  331. (BufferCommand != DB_BUF2_PAGE_PGM) &&
  332. (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
  333. return AT91C_DATAFLASH_BAD_COMMAND;
  334. /* no data to transmit or receive */
  335. pDataFlash->pDataFlashDesc->tx_data_size = 0;
  336. cmdsize = 4;
  337. if (pDataFlash->pDevice->pages_number >= 16384)
  338. cmdsize = 5;
  339. /* Send the command to the dataflash */
  340. return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest));
  341. }
  342. /*------------------------------------------------------------------------------*/
  343. /* Function Name : AT91F_PartialPageWrite */
  344. /* Object : Erase partially a page */
  345. /* Input Parameters : <page> = page number */
  346. /* : <AdrInpage> = adr to begin the fading */
  347. /* : <length> = Number of bytes to erase */
  348. /*------------------------------------------------------------------------------*/
  349. static AT91S_DataFlashStatus AT91F_PartialPageWrite (
  350. AT91PS_DataFlash pDataFlash,
  351. unsigned char *src,
  352. unsigned int dest,
  353. unsigned int size)
  354. {
  355. unsigned int page;
  356. unsigned int AdrInPage;
  357. page = dest / (pDataFlash->pDevice->pages_size);
  358. AdrInPage = dest % (pDataFlash->pDevice->pages_size);
  359. /* Read the contents of the page in the Sram Buffer */
  360. AT91F_MainMemoryToBufferTransfer(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
  361. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  362. /*Update the SRAM buffer */
  363. AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
  364. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  365. /* Erase page if a 128 Mbits device */
  366. if (pDataFlash->pDevice->pages_number >= 16384)
  367. {
  368. AT91F_PageErase(pDataFlash, page);
  369. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  370. }
  371. /* Rewrite the modified Sram Buffer in the main memory */
  372. return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
  373. (page*pDataFlash->pDevice->pages_size)));
  374. }
  375. /*------------------------------------------------------------------------------*/
  376. /* Function Name : AT91F_DataFlashWrite */
  377. /* Object : */
  378. /* Input Parameters : <*src> = Source buffer */
  379. /* : <dest> = dataflash adress */
  380. /* : <size> = data buffer size */
  381. /*------------------------------------------------------------------------------*/
  382. AT91S_DataFlashStatus AT91F_DataFlashWrite(
  383. AT91PS_DataFlash pDataFlash,
  384. unsigned char *src,
  385. int dest,
  386. int size )
  387. {
  388. unsigned int length;
  389. unsigned int page;
  390. unsigned int status;
  391. AT91F_SpiEnable(pDataFlash->pDevice->cs);
  392. if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
  393. return AT91C_DATAFLASH_MEMORY_OVERFLOW;
  394. /* If destination does not fit a page start address */
  395. if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) {
  396. length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
  397. if (size < length)
  398. length = size;
  399. if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
  400. return AT91C_DATAFLASH_ERROR;
  401. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  402. /* Update size, source and destination pointers */
  403. size -= length;
  404. dest += length;
  405. src += length;
  406. }
  407. while (( size - pDataFlash->pDevice->pages_size ) >= 0 )
  408. {
  409. /* program dataflash page */
  410. page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
  411. status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
  412. 0, pDataFlash->pDevice->pages_size);
  413. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  414. status = AT91F_PageErase(pDataFlash, page);
  415. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  416. if (!status)
  417. return AT91C_DATAFLASH_ERROR;
  418. status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest);
  419. if(!status)
  420. return AT91C_DATAFLASH_ERROR;
  421. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  422. /* Update size, source and destination pointers */
  423. size -= pDataFlash->pDevice->pages_size ;
  424. dest += pDataFlash->pDevice->pages_size ;
  425. src += pDataFlash->pDevice->pages_size ;
  426. }
  427. /* If still some bytes to read */
  428. if ( size > 0 ) {
  429. /* program dataflash page */
  430. if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
  431. return AT91C_DATAFLASH_ERROR;
  432. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  433. }
  434. return AT91C_DATAFLASH_OK;
  435. }
  436. /*------------------------------------------------------------------------------*/
  437. /* Function Name : AT91F_DataFlashRead */
  438. /* Object : Read a block in dataflash */
  439. /* Input Parameters : */
  440. /* Return value : */
  441. /*------------------------------------------------------------------------------*/
  442. int AT91F_DataFlashRead(
  443. AT91PS_DataFlash pDataFlash,
  444. unsigned long addr,
  445. unsigned long size,
  446. char *buffer)
  447. {
  448. unsigned long SizeToRead;
  449. AT91F_SpiEnable(pDataFlash->pDevice->cs);
  450. if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
  451. return -1;
  452. while (size)
  453. {
  454. SizeToRead = (size < 0x8000)? size:0x8000;
  455. if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT)
  456. != AT91C_DATAFLASH_OK)
  457. return -1;
  458. if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (unsigned char *)buffer,
  459. SizeToRead) != AT91C_DATAFLASH_OK)
  460. return -1;
  461. size -= SizeToRead;
  462. addr += SizeToRead;
  463. buffer += SizeToRead;
  464. }
  465. return AT91C_DATAFLASH_OK;
  466. }
  467. /*------------------------------------------------------------------------------*/
  468. /* Function Name : AT91F_DataflashProbe */
  469. /* Object : */
  470. /* Input Parameters : */
  471. /* Return value : Dataflash status register */
  472. /*------------------------------------------------------------------------------*/
  473. int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
  474. {
  475. AT91F_SpiEnable(cs);
  476. AT91F_DataFlashGetStatus(pDesc);
  477. return ((pDesc->command[1] == 0xFF)? 0: (pDesc->command[1] & 0x3C));
  478. }
  479. /*------------------------------------------------------------------------------*/
  480. /* Function Name : AT91F_DataFlashErase */
  481. /* Object : */
  482. /* Input Parameters : <*pDataFlash> = Device info */
  483. /*------------------------------------------------------------------------------*/
  484. AT91S_DataFlashStatus AT91F_DataFlashErase(AT91PS_DataFlash pDataFlash)
  485. {
  486. unsigned int page;
  487. unsigned int status;
  488. AT91F_SpiEnable(pDataFlash->pDevice->cs);
  489. for(page=0; page < pDataFlash->pDevice->pages_number; page++)
  490. {
  491. /* Erase dataflash page */
  492. if ((page & 0x00FF) == 0)
  493. printf("\rERA %d/%d", page, pDataFlash->pDevice->pages_number);
  494. status = AT91F_PageErase(pDataFlash, page);
  495. AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
  496. if (!status)
  497. return AT91C_DATAFLASH_ERROR;
  498. }
  499. return AT91C_DATAFLASH_OK;
  500. }