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 : dataflash.c
11 //* Object : High level functions for the dataflash
12 //* Creation : HIi 10/10/2003
13 //*----------------------------------------------------------------------------
15 #include "dataflash.h"
17 void AT91F_InitSdram(void);
21 AT91S_DATAFLASH_INFO dataflash_info
[CFG_MAX_DATAFLASH_BANKS
];
22 static AT91S_DataFlash DataFlashInst
;
24 int cs
[][CFG_MAX_DATAFLASH_BANKS
] = {
25 {CFG_DATAFLASH_LOGIC_ADDR_CS0
, 0}, /* Logical adress, CS */
26 {CFG_DATAFLASH_LOGIC_ADDR_CS1
, 1}, /* Logical adress, CS */
27 {CFG_DATAFLASH_LOGIC_ADDR_CS2
, 2}, /* Logical adress, CS */
28 {CFG_DATAFLASH_LOGIC_ADDR_CS3
, 3}
31 #define SIZE_REGS_64M 0x2188c159
32 #define SIZE_REGS_128M 0x2188c15a
35 int AT91F_DataflashInit (void)
42 for (i
= 0; i
< CFG_MAX_DATAFLASH_BANKS
; i
++) {
43 dataflash_info
[i
].Desc
.state
= IDLE
;
44 dataflash_info
[i
].id
= 0;
45 dataflash_info
[i
].Device
.pages_number
= 0;
46 dfcode
= AT91F_DataflashProbe(cs
[i
][1], &dataflash_info
[i
].Desc
);
50 printf("\n\rflash nb %d found",i
);
51 dataflash_info
[i
].Device
.pages_number
= 4096;
52 dataflash_info
[i
].Device
.pages_size
= 528;
53 dataflash_info
[i
].Device
.page_offset
= 10;
54 dataflash_info
[i
].Device
.byte_mask
= 0x300;
55 dataflash_info
[i
].Device
.cs
= cs
[i
][1];
56 dataflash_info
[i
].Desc
.DataFlash_state
= IDLE
;
57 dataflash_info
[i
].logical_address
= cs
[i
][0];
58 dataflash_info
[i
].id
= dfcode
;
62 printf("\n\rflash nb %d found",i
);
63 dataflash_info
[i
].Device
.pages_number
= 8192;
64 dataflash_info
[i
].Device
.pages_size
= 528;
65 dataflash_info
[i
].Device
.page_offset
= 10;
66 dataflash_info
[i
].Device
.byte_mask
= 0x300;
67 dataflash_info
[i
].Device
.cs
= cs
[i
][1];
68 dataflash_info
[i
].Desc
.DataFlash_state
= IDLE
;
69 dataflash_info
[i
].logical_address
= cs
[i
][0];
70 dataflash_info
[i
].id
= dfcode
;
74 printf("\n\rflash nb %d found",i
);
75 dataflash_info
[i
].Device
.pages_number
= 8192;
76 dataflash_info
[i
].Device
.pages_size
= 1056;
77 dataflash_info
[i
].Device
.page_offset
= 11;
78 dataflash_info
[i
].Device
.byte_mask
= 0x700;
79 dataflash_info
[i
].Device
.cs
= cs
[i
][1];
80 dataflash_info
[i
].Desc
.DataFlash_state
= IDLE
;
81 dataflash_info
[i
].logical_address
= cs
[i
][0];
82 dataflash_info
[i
].id
= dfcode
;
85 printf("\n\rflash nb %d found",i
);
86 dataflash_info
[i
].Device
.pages_number
= 16384;
87 dataflash_info
[i
].Device
.pages_size
= 1056;
88 dataflash_info
[i
].Device
.page_offset
= 11;
89 dataflash_info
[i
].Device
.byte_mask
= 0x700;
90 dataflash_info
[i
].Device
.cs
= cs
[i
][1];
91 dataflash_info
[i
].Desc
.DataFlash_state
= IDLE
;
92 dataflash_info
[i
].logical_address
= cs
[i
][0];
93 dataflash_info
[i
].id
= dfcode
;
97 printf("\n\rflash nb %d not found",i
);
108 if ((dataflash_info
[2].id
!= 0) && (dataflash_info
[3].id
!= 0 )){
109 return SIZE_REGS_128M
;
112 return SIZE_REGS_64M
;
116 void AT91F_DataflashPrintInfo(void)
121 for (i
= 0; i
< CFG_MAX_DATAFLASH_BANKS
; i
++) {
122 if (dataflash_info
[i
].id
!= 0) {
123 printf ("DataFlash:");
124 switch (dataflash_info
[i
].id
) {
125 #ifndef REDUCE_CODE_SIZE
127 printf ("AT45DB161\n\r");
131 printf ("AT45DB321\n\r");
135 printf ("AT45DB642\n\r");
138 printf ("AT45DB128\n\r");
142 printf ("Nb pages: %6d\n\r"
145 "Logical address: 0x%08X\n\r",
146 (unsigned int) dataflash_info
[i
].Device
.pages_number
,
147 (unsigned int) dataflash_info
[i
].Device
.pages_size
,
148 (unsigned int) dataflash_info
[i
].Device
.pages_number
*
149 dataflash_info
[i
].Device
.pages_size
,
150 (unsigned int) dataflash_info
[i
].logical_address
);
156 /*------------------------------------------------------------------------------*/
157 /* Function Name : AT91F_DataflashSelect */
158 /* Object : Select the correct device */
159 /*------------------------------------------------------------------------------*/
160 AT91PS_DataFlash
AT91F_DataflashSelect (AT91PS_DataFlash pFlash
,
166 for (i
= 0; i
< CFG_MAX_DATAFLASH_BANKS
; i
++)
167 if ((*addr
& 0xFF000000) == dataflash_info
[i
].logical_address
) {
172 pFlash
= (AT91PS_DataFlash
) 0;
175 pFlash
->pDataFlashDesc
= &(dataflash_info
[i
].Desc
);
176 pFlash
->pDevice
= &(dataflash_info
[i
].Device
);
177 *addr
-= dataflash_info
[i
].logical_address
;
182 /*------------------------------------------------------------------------------*/
183 /* Function Name : addr_dataflash */
184 /* Object : Test if address is valid */
185 /*------------------------------------------------------------------------------*/
186 int addr_dataflash (unsigned long addr
)
191 for (i
= 0; i
< CFG_MAX_DATAFLASH_BANKS
; i
++) {
192 if ((((int) addr
) & 0xFF000000) ==
193 dataflash_info
[i
].logical_address
) {
202 /*------------------------------------------------------------------------------*/
203 /* Function Name : read_dataflash */
204 /* Object : dataflash memory read */
205 /*------------------------------------------------------------------------------*/
206 int read_dataflash (unsigned long addr
, unsigned long size
, char *result
)
208 unsigned int AddrToRead
= addr
;
209 // AT91F_DataflashPrintInfo();
210 AT91PS_DataFlash pFlash
= &DataFlashInst
;
212 pFlash
= AT91F_DataflashSelect (pFlash
, &AddrToRead
);
216 return (AT91F_DataFlashRead (pFlash
, AddrToRead
, size
, result
));
220 /*-----------------------------------------------------------------------------*/
221 /* Function Name : write_dataflash */
222 /* Object : write a block in dataflash */
223 /*-----------------------------------------------------------------------------*/
224 int write_dataflash (unsigned long addr_dest
, unsigned int addr_src
,
227 unsigned int AddrToWrite
= addr_dest
;
228 AT91PS_DataFlash pFlash
= &DataFlashInst
;
230 pFlash
= AT91F_DataflashSelect (pFlash
, &AddrToWrite
);
231 if (AddrToWrite
== -1)
234 return AT91F_DataFlashWrite (pFlash
, (unsigned char *) addr_src
, AddrToWrite
, size
);
238 int erase_dataflash(int nb
)
240 AT91PS_DataFlash pFlash
= &DataFlashInst
;
241 AT91S_DataFlashStatus status
;
244 if ( dataflash_info
[nb
].id
!= 0) {
245 AT91F_SpiEnable(pFlash
->pDevice
->cs
);
247 pFlash
->pDataFlashDesc
= &(dataflash_info
[nb
].Desc
);
248 pFlash
->pDevice
= &(dataflash_info
[nb
].Device
);
249 for ( page_nb
= 0 ; page_nb
< dataflash_info
[nb
].Device
.pages_number
; page_nb
++) {
250 if ( page_nb
% 16 == 0)
251 printf("Erase page nb %d\r\n",page_nb
);
252 status
= AT91F_PageErase(pFlash
,page_nb
);
253 AT91F_DataFlashWaitReady(pFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
255 printf("Erase page nb %d error\n",page_nb
);
256 return AT91C_DATAFLASH_ERROR
;
266 * Le sector protection register ( spr) contient la liste des secteurs de dataflash
269 * On efface le spr par la cmd
271 * Erase Sector Protection Register 3DH 2AH 7FH CFH
273 * On programme le spr par
275 * Program Sector Protection Register 3DH 2AH 7FH FCH
277 * avec dans les bytes suivants la protection des secteurs.
278 * Cette protection peut être activée par la command
280 * Enable Sector Protection 3DH 2AH 7FH A9H
282 * Le conte,u du registre peut etre lu par
284 * Read Sector Protection Register 32H xxH xxH xxH
288 * Disable Sector Protection 3DH 2AH 7FH 9AH
291 static void clear_desc( AT91S_DataflashDesc
*d
)
293 #ifdef REDUCE_CODE_SIZE
295 char *ptr1
= ( char *)d
;
296 for ( i
= 0 ; i
< sizeof(AT91S_DataflashDesc
) ; i
++)
312 d
->DataFlash_state
= 0;
325 void memset(unsigned char *ptr
,char val
, int size
)
328 for ( i
= 0 ; i
< size
; i
++) {
333 AT91S_DataflashDesc desc
;
335 t_read_lock_cmd read_lock_cmd_sector
=
344 t_read_lock_cmd read_lock_cmd_lockdown
=
353 t_read_lock_cmd read_lock_cmd_security
=
362 void AT91F_SpiEnable(int cs
);
364 void read_lock_reg(t_read_lock_cmd
*ptrcmd
)
367 unsigned char rx
[129];
371 for ( fl_nb
= 0 ; fl_nb
< CFG_MAX_DATAFLASH_BANKS
; fl_nb
++) {
373 if (dataflash_info
[fl_nb
].id
!= 0) {
374 AT91F_SpiEnable(cs
[fl_nb
][1]);
377 memset(rx
,0,sizeof(rx
));
379 desc
.tx_cmd_pt
= ptrcmd
->cmd
;
381 desc
.tx_cmd_size
= 4;
382 desc
.rx_cmd_size
= 4;
383 desc
.tx_data_size
= ptrcmd
->txsize
;
384 desc
.rx_data_size
= ptrcmd
->rxsize
;
385 desc
.tx_data_pt
= rx
;
386 desc
.rx_data_pt
= rx
;
388 AT91F_SpiWrite(&desc
);
390 if ( ptrcmd
== &read_lock_cmd_sector
) {
391 printf("read_lock_cmd_sector Lock status ");
393 if ( ptrcmd
== &read_lock_cmd_lockdown
) {
394 printf("read_lock_cmd_lockdown Lock status ");
396 if ( ptrcmd
== &read_lock_cmd_security
) {
397 printf("read_lock_cmd_security Lock status ");
399 printf("size %d flash_nb %d \n\r",ptrcmd
->rxsize
,fl_nb
);
400 for ( i
= 0 ; i
< ptrcmd
->rxsize
; i
++ ) {
404 printf("0x%02x:",rx
[i
]);
412 unsigned char clear_lock_cmd
[4]=
417 void clear_lock_reg()
420 unsigned char rx
[33];
423 memset(rx
,0,sizeof(rx
));
425 for ( fl_nb
= 0 ; fl_nb
< CFG_MAX_DATAFLASH_BANKS
; fl_nb
++) {
426 if (dataflash_info
[fl_nb
].id
!= 0) {
427 AT91F_SpiEnable(cs
[fl_nb
][1]);
431 desc
.tx_cmd_pt
= clear_lock_cmd
;
433 desc
.tx_cmd_size
= 4;
434 desc
.rx_cmd_size
= 4;
435 AT91F_SpiWrite(&desc
);
440 unsigned char lock_unlock_cmd
[4]=
445 unsigned char enable_lock_unlock_cmd
[4]=
450 unsigned char disable_lock_unlock_cmd
[4]=
456 void flash_en_lock_unlock(unsigned char *cmd
)
458 unsigned char rxf
[4];
459 unsigned char rx
[33];
462 desc
.tx_cmd_pt
= cmd
;
463 desc
.rx_cmd_pt
= rxf
;
464 desc
.tx_cmd_size
= 4;
465 desc
.rx_cmd_size
= 4;
467 AT91F_SpiWrite(&desc
);
470 void flash_cmd_lock_unlock()
472 unsigned char rxf
[4];
473 unsigned char rx
[33];
474 memset(rx
,0,sizeof(rx
));
477 desc
.tx_cmd_pt
= lock_unlock_cmd
;
478 desc
.rx_cmd_pt
= rxf
;
479 desc
.tx_cmd_size
= 4;
480 desc
.rx_cmd_size
= 4;
481 desc
.tx_data_size
= 32;
482 desc
.rx_data_size
= 32;
483 desc
.tx_data_pt
= rx
;
484 desc
.rx_data_pt
= rx
;
486 AT91F_SpiWrite(&desc
);
489 void flash_lock_reg()
493 for ( fl_nb
= 0 ; fl_nb
< CFG_MAX_DATAFLASH_BANKS
; fl_nb
++) {
494 if (dataflash_info
[fl_nb
].id
!= 0) {
495 AT91F_SpiEnable(cs
[fl_nb
][1]);
496 flash_en_lock_unlock(enable_lock_unlock_cmd
);
497 flash_cmd_lock_unlock();
504 void flash_unlock_reg()
509 for ( fl_nb
= 0 ; fl_nb
< CFG_MAX_DATAFLASH_BANKS
; fl_nb
++) {
510 if (dataflash_info
[fl_nb
].id
!= 0) {
511 AT91F_SpiEnable(cs
[fl_nb
][1]);
512 flash_cmd_lock_unlock();
513 flash_en_lock_unlock(disable_lock_unlock_cmd
);