1 /* Driver for ATMEL DataFlash support
2 * Author : Hamid Ikdoumi (Atmel)
4 * SPDX-License-Identifier: GPL-2.0+
14 extern unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc
);
15 extern void AT91F_SpiEnable(int cs
);
17 #define AT91C_TIMEOUT_WRDY 200000
19 /*----------------------------------------------------------------------*/
20 /* \fn AT91F_DataFlashSendCommand */
21 /* \brief Generic function to send a command to the dataflash */
22 /*----------------------------------------------------------------------*/
23 AT91S_DataFlashStatus
AT91F_DataFlashSendCommand(AT91PS_DataFlash pDataFlash
,
26 unsigned int DataflashAddress
)
30 if ((pDataFlash
->pDataFlashDesc
->state
) != IDLE
)
31 return DATAFLASH_BUSY
;
33 /* process the address to obtain page address and byte address */
34 adr
= ((DataflashAddress
/ (pDataFlash
->pDevice
->pages_size
)) <<
35 pDataFlash
->pDevice
->page_offset
) +
36 (DataflashAddress
% (pDataFlash
->pDevice
->pages_size
));
38 /* fill the command buffer */
39 pDataFlash
->pDataFlashDesc
->command
[0] = OpCode
;
40 if (pDataFlash
->pDevice
->pages_number
>= 16384) {
41 pDataFlash
->pDataFlashDesc
->command
[1] =
42 (unsigned char)((adr
& 0x0F000000) >> 24);
43 pDataFlash
->pDataFlashDesc
->command
[2] =
44 (unsigned char)((adr
& 0x00FF0000) >> 16);
45 pDataFlash
->pDataFlashDesc
->command
[3] =
46 (unsigned char)((adr
& 0x0000FF00) >> 8);
47 pDataFlash
->pDataFlashDesc
->command
[4] =
48 (unsigned char)(adr
& 0x000000FF);
50 pDataFlash
->pDataFlashDesc
->command
[1] =
51 (unsigned char)((adr
& 0x00FF0000) >> 16);
52 pDataFlash
->pDataFlashDesc
->command
[2] =
53 (unsigned char)((adr
& 0x0000FF00) >> 8);
54 pDataFlash
->pDataFlashDesc
->command
[3] =
55 (unsigned char)(adr
& 0x000000FF);
56 pDataFlash
->pDataFlashDesc
->command
[4] = 0;
58 pDataFlash
->pDataFlashDesc
->command
[5] = 0;
59 pDataFlash
->pDataFlashDesc
->command
[6] = 0;
60 pDataFlash
->pDataFlashDesc
->command
[7] = 0;
62 /* Initialize the SpiData structure for the spi write fuction */
63 pDataFlash
->pDataFlashDesc
->tx_cmd_pt
=
64 pDataFlash
->pDataFlashDesc
->command
;
65 pDataFlash
->pDataFlashDesc
->tx_cmd_size
= CmdSize
;
66 pDataFlash
->pDataFlashDesc
->rx_cmd_pt
=
67 pDataFlash
->pDataFlashDesc
->command
;
68 pDataFlash
->pDataFlashDesc
->rx_cmd_size
= CmdSize
;
70 /* send the command and read the data */
71 return AT91F_SpiWrite(pDataFlash
->pDataFlashDesc
);
74 /*----------------------------------------------------------------------*/
75 /* \fn AT91F_DataFlashGetStatus */
76 /* \brief Read the status register of the dataflash */
77 /*----------------------------------------------------------------------*/
78 AT91S_DataFlashStatus
AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc
)
80 AT91S_DataFlashStatus status
;
82 /* if a transfert is in progress ==> return 0 */
83 if ((pDesc
->state
) != IDLE
)
84 return DATAFLASH_BUSY
;
86 /* first send the read status command (D7H) */
87 pDesc
->command
[0] = DB_STATUS
;
88 pDesc
->command
[1] = 0;
90 pDesc
->DataFlash_state
= GET_STATUS
;
91 pDesc
->tx_data_size
= 0; /* Transmit the command */
92 /* and receive response */
93 pDesc
->tx_cmd_pt
= pDesc
->command
;
94 pDesc
->rx_cmd_pt
= pDesc
->command
;
95 pDesc
->rx_cmd_size
= 2;
96 pDesc
->tx_cmd_size
= 2;
97 status
= AT91F_SpiWrite(pDesc
);
99 pDesc
->DataFlash_state
= *((unsigned char *)(pDesc
->rx_cmd_pt
) + 1);
104 /*----------------------------------------------------------------------*/
105 /* \fn AT91F_DataFlashWaitReady */
106 /* \brief wait for dataflash ready (bit7 of the status register == 1) */
107 /*----------------------------------------------------------------------*/
108 AT91S_DataFlashStatus
AT91F_DataFlashWaitReady(AT91PS_DataflashDesc
110 unsigned int timeout
)
112 pDataFlashDesc
->DataFlash_state
= IDLE
;
115 AT91F_DataFlashGetStatus(pDataFlashDesc
);
117 } while (((pDataFlashDesc
->DataFlash_state
& 0x80) != 0x80) &&
120 if ((pDataFlashDesc
->DataFlash_state
& 0x80) != 0x80)
121 return DATAFLASH_ERROR
;
126 /*--------------------------------------------------------------------------*/
127 /* Function Name : AT91F_DataFlashContinuousRead */
128 /* Object : Continuous stream Read */
129 /* Input Parameters : DataFlash Service */
130 /* : <src> = dataflash address */
131 /* : <*dataBuffer> = data buffer pointer */
132 /* : <sizeToRead> = data buffer size */
133 /* Return value : State of the dataflash */
134 /*--------------------------------------------------------------------------*/
135 AT91S_DataFlashStatus
AT91F_DataFlashContinuousRead(
136 AT91PS_DataFlash pDataFlash
,
138 unsigned char *dataBuffer
,
141 AT91S_DataFlashStatus status
;
142 /* Test the size to read in the device */
143 if ((src
+ sizeToRead
) >
144 (pDataFlash
->pDevice
->pages_size
*
145 (pDataFlash
->pDevice
->pages_number
)))
146 return DATAFLASH_MEMORY_OVERFLOW
;
148 pDataFlash
->pDataFlashDesc
->rx_data_pt
= dataBuffer
;
149 pDataFlash
->pDataFlashDesc
->rx_data_size
= sizeToRead
;
150 pDataFlash
->pDataFlashDesc
->tx_data_pt
= dataBuffer
;
151 pDataFlash
->pDataFlashDesc
->tx_data_size
= sizeToRead
;
153 status
= AT91F_DataFlashSendCommand(
154 pDataFlash
, DB_CONTINUOUS_ARRAY_READ
, 8, src
);
155 /* Send the command to the dataflash */
159 /*---------------------------------------------------------------------------*/
160 /* Function Name : AT91F_DataFlashPagePgmBuf */
161 /* Object : Main memory page program thru buffer 1 or buffer 2 */
162 /* Input Parameters : DataFlash Service */
163 /* : <*src> = Source buffer */
164 /* : <dest> = dataflash destination address */
165 /* : <SizeToWrite> = data buffer size */
166 /* Return value : State of the dataflash */
167 /*---------------------------------------------------------------------------*/
168 AT91S_DataFlashStatus
AT91F_DataFlashPagePgmBuf(AT91PS_DataFlash pDataFlash
,
171 unsigned int SizeToWrite
)
174 pDataFlash
->pDataFlashDesc
->tx_data_pt
= src
;
175 pDataFlash
->pDataFlashDesc
->tx_data_size
= SizeToWrite
;
176 pDataFlash
->pDataFlashDesc
->rx_data_pt
= src
;
177 pDataFlash
->pDataFlashDesc
->rx_data_size
= SizeToWrite
;
180 /* Send the command to the dataflash */
181 if (pDataFlash
->pDevice
->pages_number
>= 16384)
183 return (AT91F_DataFlashSendCommand(
184 pDataFlash
, DB_PAGE_PGM_BUF1
, cmdsize
, dest
));
187 /*---------------------------------------------------------------------------*/
188 /* Function Name : AT91F_MainMemoryToBufferTransfert */
189 /* Object : Read a page in the SRAM Buffer 1 or 2 */
190 /* Input Parameters : DataFlash Service */
191 /* : Page concerned */
193 /* Return value : State of the dataflash */
194 /*---------------------------------------------------------------------------*/
195 AT91S_DataFlashStatus
AT91F_MainMemoryToBufferTransfert(
203 /* Test if the buffer command is legal */
204 if ((BufferCommand
!= DB_PAGE_2_BUF1_TRF
) &&
205 (BufferCommand
!= DB_PAGE_2_BUF2_TRF
)) {
206 return DATAFLASH_BAD_COMMAND
;
209 /* no data to transmit or receive */
210 pDataFlash
->pDataFlashDesc
->tx_data_size
= 0;
212 if (pDataFlash
->pDevice
->pages_number
>= 16384)
214 return (AT91F_DataFlashSendCommand(
215 pDataFlash
, BufferCommand
, cmdsize
,
216 page
* pDataFlash
->pDevice
->pages_size
));
219 /*-------------------------------------------------------------------------- */
220 /* Function Name : AT91F_DataFlashWriteBuffer */
221 /* Object : Write data to the internal sram buffer 1 or 2 */
222 /* Input Parameters : DataFlash Service */
223 /* : <BufferCommand> = command to write buffer1 or 2 */
224 /* : <*dataBuffer> = data buffer to write */
225 /* : <bufferAddress> = address in the internal buffer */
226 /* : <SizeToWrite> = data buffer size */
227 /* Return value : State of the dataflash */
228 /*---------------------------------------------------------------------------*/
229 AT91S_DataFlashStatus
AT91F_DataFlashWriteBuffer(
230 AT91PS_DataFlash pDataFlash
,
231 unsigned char BufferCommand
,
232 unsigned char *dataBuffer
,
233 unsigned int bufferAddress
,
237 /* Test if the buffer command is legal */
238 if ((BufferCommand
!= DB_BUF1_WRITE
) &&
239 (BufferCommand
!= DB_BUF2_WRITE
)) {
240 return DATAFLASH_BAD_COMMAND
;
243 /* buffer address must be lower than page size */
244 if (bufferAddress
> pDataFlash
->pDevice
->pages_size
)
245 return DATAFLASH_BAD_ADDRESS
;
247 if ((pDataFlash
->pDataFlashDesc
->state
) != IDLE
)
248 return DATAFLASH_BUSY
;
250 /* Send first Write Command */
251 pDataFlash
->pDataFlashDesc
->command
[0] = BufferCommand
;
252 pDataFlash
->pDataFlashDesc
->command
[1] = 0;
253 if (pDataFlash
->pDevice
->pages_number
>= 16384) {
254 pDataFlash
->pDataFlashDesc
->command
[2] = 0;
255 pDataFlash
->pDataFlashDesc
->command
[3] =
256 (unsigned char)(((unsigned int)(bufferAddress
&
257 pDataFlash
->pDevice
->
259 pDataFlash
->pDataFlashDesc
->command
[4] =
260 (unsigned char)((unsigned int)bufferAddress
& 0x00FF);
263 pDataFlash
->pDataFlashDesc
->command
[2] =
264 (unsigned char)(((unsigned int)(bufferAddress
&
265 pDataFlash
->pDevice
->
267 pDataFlash
->pDataFlashDesc
->command
[3] =
268 (unsigned char)((unsigned int)bufferAddress
& 0x00FF);
269 pDataFlash
->pDataFlashDesc
->command
[4] = 0;
273 pDataFlash
->pDataFlashDesc
->tx_cmd_pt
=
274 pDataFlash
->pDataFlashDesc
->command
;
275 pDataFlash
->pDataFlashDesc
->tx_cmd_size
= cmdsize
;
276 pDataFlash
->pDataFlashDesc
->rx_cmd_pt
=
277 pDataFlash
->pDataFlashDesc
->command
;
278 pDataFlash
->pDataFlashDesc
->rx_cmd_size
= cmdsize
;
280 pDataFlash
->pDataFlashDesc
->rx_data_pt
= dataBuffer
;
281 pDataFlash
->pDataFlashDesc
->tx_data_pt
= dataBuffer
;
282 pDataFlash
->pDataFlashDesc
->rx_data_size
= SizeToWrite
;
283 pDataFlash
->pDataFlashDesc
->tx_data_size
= SizeToWrite
;
285 return AT91F_SpiWrite(pDataFlash
->pDataFlashDesc
);
288 /*---------------------------------------------------------------------------*/
289 /* Function Name : AT91F_PageErase */
290 /* Object : Erase a page */
291 /* Input Parameters : DataFlash Service */
292 /* : Page concerned */
294 /* Return value : State of the dataflash */
295 /*---------------------------------------------------------------------------*/
296 AT91S_DataFlashStatus
AT91F_PageErase(
297 AT91PS_DataFlash pDataFlash
,
301 /* Test if the buffer command is legal */
302 /* no data to transmit or receive */
303 pDataFlash
->pDataFlashDesc
->tx_data_size
= 0;
306 if (pDataFlash
->pDevice
->pages_number
>= 16384)
308 return (AT91F_DataFlashSendCommand(pDataFlash
,
309 DB_PAGE_ERASE
, cmdsize
,
310 page
* pDataFlash
->pDevice
->pages_size
));
313 /*---------------------------------------------------------------------------*/
314 /* Function Name : AT91F_BlockErase */
315 /* Object : Erase a Block */
316 /* Input Parameters : DataFlash Service */
317 /* : Page concerned */
319 /* Return value : State of the dataflash */
320 /*---------------------------------------------------------------------------*/
321 AT91S_DataFlashStatus
AT91F_BlockErase(
322 AT91PS_DataFlash pDataFlash
,
326 /* Test if the buffer command is legal */
327 /* no data to transmit or receive */
328 pDataFlash
->pDataFlashDesc
->tx_data_size
= 0;
330 if (pDataFlash
->pDevice
->pages_number
>= 16384)
332 return (AT91F_DataFlashSendCommand(pDataFlash
, DB_BLOCK_ERASE
, cmdsize
,
334 pDataFlash
->pDevice
->pages_size
));
337 /*---------------------------------------------------------------------------*/
338 /* Function Name : AT91F_WriteBufferToMain */
339 /* Object : Write buffer to the main memory */
340 /* Input Parameters : DataFlash Service */
341 /* : <BufferCommand> = command to send to buffer1 or buffer2 */
342 /* : <dest> = main memory address */
343 /* Return value : State of the dataflash */
344 /*---------------------------------------------------------------------------*/
345 AT91S_DataFlashStatus
AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash
,
346 unsigned char BufferCommand
,
350 /* Test if the buffer command is correct */
351 if ((BufferCommand
!= DB_BUF1_PAGE_PGM
) &&
352 (BufferCommand
!= DB_BUF1_PAGE_ERASE_PGM
) &&
353 (BufferCommand
!= DB_BUF2_PAGE_PGM
) &&
354 (BufferCommand
!= DB_BUF2_PAGE_ERASE_PGM
))
355 return DATAFLASH_BAD_COMMAND
;
357 /* no data to transmit or receive */
358 pDataFlash
->pDataFlashDesc
->tx_data_size
= 0;
361 if (pDataFlash
->pDevice
->pages_number
>= 16384)
363 /* Send the command to the dataflash */
364 return (AT91F_DataFlashSendCommand(pDataFlash
, BufferCommand
,
368 /*---------------------------------------------------------------------------*/
369 /* Function Name : AT91F_PartialPageWrite */
370 /* Object : Erase partielly a page */
371 /* Input Parameters : <page> = page number */
372 /* : <AdrInpage> = adr to begin the fading */
373 /* : <length> = Number of bytes to erase */
374 /*---------------------------------------------------------------------------*/
375 AT91S_DataFlashStatus
AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash
,
381 unsigned int AdrInPage
;
383 page
= dest
/ (pDataFlash
->pDevice
->pages_size
);
384 AdrInPage
= dest
% (pDataFlash
->pDevice
->pages_size
);
386 /* Read the contents of the page in the Sram Buffer */
387 AT91F_MainMemoryToBufferTransfert(pDataFlash
, DB_PAGE_2_BUF1_TRF
, page
);
388 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
390 /*Update the SRAM buffer */
391 AT91F_DataFlashWriteBuffer(pDataFlash
, DB_BUF1_WRITE
, src
,
394 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
397 /* Erase page if a 128 Mbits device */
398 if (pDataFlash
->pDevice
->pages_number
>= 16384) {
399 AT91F_PageErase(pDataFlash
, page
);
400 /* Rewrite the modified Sram Buffer in the main memory */
401 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
405 /* Rewrite the modified Sram Buffer in the main memory */
406 return (AT91F_WriteBufferToMain(pDataFlash
, DB_BUF1_PAGE_ERASE_PGM
,
408 pDataFlash
->pDevice
->pages_size
)));
411 /*---------------------------------------------------------------------------*/
412 /* Function Name : AT91F_DataFlashWrite */
414 /* Input Parameters : <*src> = Source buffer */
415 /* : <dest> = dataflash adress */
416 /* : <size> = data buffer size */
417 /*---------------------------------------------------------------------------*/
418 AT91S_DataFlashStatus
AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash
,
426 AT91F_SpiEnable(pDataFlash
->pDevice
->cs
);
428 if ((dest
+ size
) > (pDataFlash
->pDevice
->pages_size
*
429 (pDataFlash
->pDevice
->pages_number
)))
430 return DATAFLASH_MEMORY_OVERFLOW
;
432 /* If destination does not fit a page start address */
433 if ((dest
% ((unsigned int)(pDataFlash
->pDevice
->pages_size
))) != 0) {
435 pDataFlash
->pDevice
->pages_size
-
436 (dest
% ((unsigned int)(pDataFlash
->pDevice
->pages_size
)));
441 if (!AT91F_PartialPageWrite(pDataFlash
, src
, dest
, length
))
442 return DATAFLASH_ERROR
;
444 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
447 /* Update size, source and destination pointers */
453 while ((size
- pDataFlash
->pDevice
->pages_size
) >= 0) {
454 /* program dataflash page */
455 page
= (unsigned int)dest
/ (pDataFlash
->pDevice
->pages_size
);
457 status
= AT91F_DataFlashWriteBuffer(pDataFlash
,
458 DB_BUF1_WRITE
, src
, 0,
459 pDataFlash
->pDevice
->
461 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
464 status
= AT91F_PageErase(pDataFlash
, page
);
465 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
468 return DATAFLASH_ERROR
;
470 status
= AT91F_WriteBufferToMain(pDataFlash
,
471 DB_BUF1_PAGE_PGM
, dest
);
473 return DATAFLASH_ERROR
;
475 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
478 /* Update size, source and destination pointers */
479 size
-= pDataFlash
->pDevice
->pages_size
;
480 dest
+= pDataFlash
->pDevice
->pages_size
;
481 src
+= pDataFlash
->pDevice
->pages_size
;
484 /* If still some bytes to read */
486 /* program dataflash page */
487 if (!AT91F_PartialPageWrite(pDataFlash
, src
, dest
, size
))
488 return DATAFLASH_ERROR
;
490 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
496 /*---------------------------------------------------------------------------*/
497 /* Function Name : AT91F_DataFlashRead */
498 /* Object : Read a block in dataflash */
499 /* Input Parameters : */
501 /*---------------------------------------------------------------------------*/
502 int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash
,
503 unsigned long addr
, unsigned long size
, char *buffer
)
505 unsigned long SizeToRead
;
507 AT91F_SpiEnable(pDataFlash
->pDevice
->cs
);
509 if (AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
510 AT91C_TIMEOUT_WRDY
) != DATAFLASH_OK
)
514 SizeToRead
= (size
< 0x8000) ? size
: 0x8000;
516 if (AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
,
517 AT91C_TIMEOUT_WRDY
) !=
521 if (AT91F_DataFlashContinuousRead(pDataFlash
, addr
,
523 SizeToRead
) != DATAFLASH_OK
)
528 buffer
+= SizeToRead
;
534 /*---------------------------------------------------------------------------*/
535 /* Function Name : AT91F_DataflashProbe */
537 /* Input Parameters : */
538 /* Return value : Dataflash status register */
539 /*---------------------------------------------------------------------------*/
540 int AT91F_DataflashProbe(int cs
, AT91PS_DataflashDesc pDesc
)
543 AT91F_DataFlashGetStatus(pDesc
);
544 return ((pDesc
->command
[1] == 0xFF) ? 0 : pDesc
->command
[1] & 0x3C);