Merge branch 'master' of /media/usbdisk-11/IER/reference/romboot
[romboot.git] / dataflash.cpp
blob861625849503ba2dcd51292e4bcdc64c4e16cfc0
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"
16 #include "com.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)
37 int i;
38 int dfcode;
40 AT91F_SpiInit ();
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);
48 switch (dfcode) {
49 #if 0
50 case AT45DB161:
51 printf("\n\rflash nb %d found",i);
52 dataflash_info[i].Device.pages_number = 4096;
53 dataflash_info[i].Device.pages_size = 528;
54 dataflash_info[i].Device.page_offset = 10;
55 dataflash_info[i].Device.byte_mask = 0x300;
56 dataflash_info[i].Device.cs = cs[i][1];
57 dataflash_info[i].Desc.DataFlash_state = IDLE;
58 dataflash_info[i].logical_address = cs[i][0];
59 dataflash_info[i].id = dfcode;
60 break;
62 case AT45DB321:
63 printf("\n\rflash nb %d found",i);
64 dataflash_info[i].Device.pages_number = 8192;
65 dataflash_info[i].Device.pages_size = 528;
66 dataflash_info[i].Device.page_offset = 10;
67 dataflash_info[i].Device.byte_mask = 0x300;
68 dataflash_info[i].Device.cs = cs[i][1];
69 dataflash_info[i].Desc.DataFlash_state = IDLE;
70 dataflash_info[i].logical_address = cs[i][0];
71 dataflash_info[i].id = dfcode;
72 break;
73 #endif
75 case AT45DB642:
76 printf("\n\rflash nb %d found",i);
77 dataflash_info[i].Device.pages_number = 8192;
78 dataflash_info[i].Device.pages_size = 1056;
79 dataflash_info[i].Device.page_offset = 11;
80 dataflash_info[i].Device.byte_mask = 0x700;
81 dataflash_info[i].Device.cs = cs[i][1];
82 dataflash_info[i].Desc.DataFlash_state = IDLE;
83 dataflash_info[i].logical_address = cs[i][0];
84 dataflash_info[i].id = dfcode;
85 break;
86 #if 0
87 case AT45DB128:
88 printf("\n\rflash nb %d found",i);
89 dataflash_info[i].Device.pages_number = 16384;
90 dataflash_info[i].Device.pages_size = 1056;
91 dataflash_info[i].Device.page_offset = 11;
92 dataflash_info[i].Device.byte_mask = 0x700;
93 dataflash_info[i].Device.cs = cs[i][1];
94 dataflash_info[i].Desc.DataFlash_state = IDLE;
95 dataflash_info[i].logical_address = cs[i][0];
96 dataflash_info[i].id = dfcode;
97 break;
98 #endif
99 default:
100 printf("\n\rflash nb %d not found",i);
101 break;
104 printf("\n\r");
105 AT91F_InitSdram();
106 return (1);
109 int get_size_reg()
111 if ((dataflash_info[2].id != 0) && (dataflash_info[3].id != 0 )){
112 return SIZE_REGS_128M;
114 else {
115 return SIZE_REGS_64M;
119 void AT91F_DataflashPrintInfo(void)
121 int i;
122 int *pregister;
124 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
125 if (dataflash_info[i].id != 0) {
126 printf ("Flash:");
127 switch (dataflash_info[i].id) {
128 #ifndef REDUCE_CODE_SIZE
129 case AT45DB161:
130 printf ("AT45DB161\n\r");
131 break;
133 case AT45DB321:
134 printf ("AT45DB321\n\r");
135 break;
136 #endif
137 case AT45DB642:
138 printf ("AT45DB642\n\r");
139 break;
140 #ifndef REDUCE_CODE_SIZE
141 case AT45DB128:
142 printf ("AT45DB128\n\r");
143 break;
144 #endif
146 printf ("Nb pages: %6d\n\r"
147 "Page Sz: %6d\n\r"
148 "Sz=%8d bytes\n\r"
149 "Logical addr: 0x%08X\n\r",
150 (unsigned int) dataflash_info[i].Device.pages_number,
151 (unsigned int) dataflash_info[i].Device.pages_size,
152 (unsigned int) dataflash_info[i].Device.pages_number *
153 dataflash_info[i].Device.pages_size,
154 (unsigned int) dataflash_info[i].logical_address);
160 /*------------------------------------------------------------------------------*/
161 /* Function Name : AT91F_DataflashSelect */
162 /* Object : Select the correct device */
163 /*------------------------------------------------------------------------------*/
164 AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash,
165 unsigned int *addr)
167 char addr_valid = 0;
168 int i;
170 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
171 if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) {
172 addr_valid = 1;
173 break;
175 if (!addr_valid) {
176 pFlash = (AT91PS_DataFlash) 0;
177 return pFlash;
179 pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
180 pFlash->pDevice = &(dataflash_info[i].Device);
181 *addr -= dataflash_info[i].logical_address;
182 return (pFlash);
186 /*------------------------------------------------------------------------------*/
187 /* Function Name : addr_dataflash */
188 /* Object : Test if address is valid */
189 /*------------------------------------------------------------------------------*/
190 int addr_dataflash (unsigned long addr)
192 int addr_valid = 0;
193 int i;
195 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
196 if ((((int) addr) & 0xFF000000) ==
197 dataflash_info[i].logical_address) {
198 addr_valid = 1;
199 break;
203 return addr_valid;
206 /*------------------------------------------------------------------------------*/
207 /* Function Name : read_dataflash */
208 /* Object : dataflash memory read */
209 /*------------------------------------------------------------------------------*/
210 int read_dataflash (unsigned long addr, unsigned long size, char *result)
212 unsigned int AddrToRead = addr;
213 // AT91F_DataflashPrintInfo();
214 AT91PS_DataFlash pFlash = &DataFlashInst;
216 pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
217 if (pFlash == 0)
218 return -1;
220 return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
224 /*-----------------------------------------------------------------------------*/
225 /* Function Name : write_dataflash */
226 /* Object : write a block in dataflash */
227 /*-----------------------------------------------------------------------------*/
228 int write_dataflash (unsigned long addr_dest, unsigned int addr_src,
229 unsigned int size)
231 unsigned int AddrToWrite = addr_dest;
232 AT91PS_DataFlash pFlash = &DataFlashInst;
234 pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
235 if (AddrToWrite == -1)
236 return -1;
238 return AT91F_DataFlashWrite (pFlash, (unsigned char *) addr_src, AddrToWrite, size);
242 int erase_dataflash(int nb)
244 AT91PS_DataFlash pFlash = &DataFlashInst;
245 AT91S_DataFlashStatus status;
246 int page_nb;
248 if ( dataflash_info[nb].id != 0) {
249 AT91F_SpiEnable(pFlash->pDevice->cs);
251 pFlash->pDataFlashDesc = &(dataflash_info[nb].Desc);
252 pFlash->pDevice = &(dataflash_info[nb].Device);
253 for ( page_nb = 0 ; page_nb < dataflash_info[nb].Device.pages_number ; page_nb++) {
254 if ( page_nb % 16 == 0)
255 printf("Erase page nb %d\r\n",page_nb);
256 status = AT91F_PageErase(pFlash,page_nb);
257 AT91F_DataFlashWaitReady(pFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
258 if (!status) {
259 printf("Erase page nb %d error\n",page_nb);
260 return AT91C_DATAFLASH_ERROR;
270 * Le sector protection register ( spr) contient la liste des secteurs de dataflash
271 * a protéger.
273 * On efface le spr par la cmd
275 * Erase Sector Protection Register 3DH 2AH 7FH CFH
277 * On programme le spr par
279 * Program Sector Protection Register 3DH 2AH 7FH FCH
281 * avec dans les bytes suivants la protection des secteurs.
282 * Cette protection peut être activée par la command
284 * Enable Sector Protection 3DH 2AH 7FH A9H
286 * Le conte,u du registre peut etre lu par
288 * Read Sector Protection Register 32H xxH xxH xxH
290 * et désactivée par
292 * Disable Sector Protection 3DH 2AH 7FH 9AH
295 void memset(unsigned char *ptr,char val , int size)
297 int i;
298 for ( i = 0 ; i < size ; i++) {
299 *ptr = val;
300 ptr++;
304 static void clear_desc( AT91S_DataflashDesc *d)
306 memset((unsigned char *)d,0,sizeof(AT91S_DataflashDesc));
310 AT91S_DataflashDesc desc;
312 t_read_lock_cmd read_lock_cmd_sector =
315 0x32,0x00,0x00,0x00
321 t_read_lock_cmd read_lock_cmd_lockdown=
324 0x35,0x00,0x00,0x00
330 t_read_lock_cmd read_lock_cmd_security=
333 0x77,0x00,0x00,0x00
335 128,
339 void AT91F_SpiEnable(int cs);
341 void send_spi(int fl_nb)
343 AT91PS_DataFlash pFlash = &DataFlashInst;
344 if (dataflash_info[fl_nb].id != 0) {
345 AT91F_SpiEnable(cs[fl_nb][1]);
346 AT91F_SpiWrite(&desc);
347 pFlash->pDataFlashDesc = &(dataflash_info[fl_nb].Desc);
348 AT91F_DataFlashWaitReady(pFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
352 void read_lock_reg(t_read_lock_cmd *ptrcmd)
354 int i;
355 unsigned char rx[129];
356 char *ptr;
357 int fl_nb;
359 for ( fl_nb = 0 ; fl_nb < CFG_MAX_DATAFLASH_BANKS ; fl_nb++) {
361 clear_desc(&desc);
363 memset(rx,0,sizeof(rx));
364 rx[0] = 8;
365 desc.tx_cmd_pt = ptrcmd->cmd;
366 desc.rx_cmd_pt = rx;
367 desc.tx_cmd_size = 4;
368 desc.rx_cmd_size = 4;
369 desc.tx_data_size = ptrcmd->txsize;
370 desc.rx_data_size = ptrcmd->rxsize;
371 desc.tx_data_pt = rx;
372 desc.rx_data_pt = rx;
373 send_spi(fl_nb);
374 printf("\n\r");
375 if (dataflash_info[fl_nb].id != 0) {
376 if ( ptrcmd == &read_lock_cmd_sector ) {
377 printf("Lock status reg ");
379 if ( ptrcmd == &read_lock_cmd_lockdown ) {
380 printf("lockdown status reg ");
382 if ( ptrcmd == &read_lock_cmd_security ) {
383 printf("security reg ");
385 for ( i = 0 ; i < ptrcmd->rxsize ; i++ ) {
386 if ((i % 16) == 0) {
387 printf("\n\r");
389 printf("0x%02x:",rx[i]);
391 printf("\n\r");
396 unsigned char clear_lock_cmd[4]=
398 0x3D,0x2A,0x7F,0xCF
402 unsigned char lock_unlock_cmd[4]=
404 0x3D,0x2A,0x7F,0xFC
407 unsigned char enable_lock_unlock_cmd[4]=
409 0x3D,0x2A,0x7F,0xA9
412 unsigned char disable_lock_unlock_cmd[4]=
414 0x3D,0x2A,0x7F,0x9A
417 void flash_en_lock_unlock(int fl_nb,unsigned char *cmd)
419 unsigned char rxf[4];
420 unsigned char rx[33];
421 clear_desc(&desc);
422 desc.tx_cmd_pt = cmd;
423 desc.rx_cmd_pt = rxf;
424 desc.tx_cmd_size = 4;
425 desc.rx_cmd_size = 4;
426 send_spi(fl_nb);
429 void write_lock_reg(int fl_nb,int val)
431 unsigned char rxf[4];
432 unsigned char rx[33];
433 memset(rx,val,sizeof(rx));
434 clear_desc(&desc);
435 desc.tx_cmd_pt = lock_unlock_cmd;
436 desc.rx_cmd_pt = rxf;
437 desc.tx_cmd_size = 4;
438 desc.rx_cmd_size = 4;
439 desc.tx_data_size = 32;
440 desc.rx_data_size = 32;
441 desc.tx_data_pt = rx;
442 desc.rx_data_pt = rx;
443 send_spi(fl_nb);
446 void erase_lock_reg(int fl_nb)
448 unsigned char rx[5];
449 memset(rx,0,sizeof(rx));
450 clear_desc(&desc);
451 desc.tx_cmd_pt = clear_lock_cmd;
452 desc.rx_cmd_pt = rx;
453 desc.tx_cmd_size = 4;
454 desc.rx_cmd_size = 4;
455 send_spi(fl_nb);
458 void set_lock_reg(int fl_nb)
460 erase_lock_reg(fl_nb);
461 write_lock_reg(fl_nb,0xff);
464 void clr_lock_reg(int fl_nb)
466 erase_lock_reg(fl_nb);
467 write_lock_reg(fl_nb,0);
470 void flash_enable_lock(int fl_nb)
472 flash_en_lock_unlock(fl_nb,enable_lock_unlock_cmd);
475 void flash_disable_lock(int fl_nb)
477 flash_en_lock_unlock(fl_nb,disable_lock_unlock_cmd);