Modify romboot to display lock registers correctly
[romboot.git] / dataflash.cpp
blobc785f5add9edb4e81b193c35f8b9f164f958891e
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 case AT45DB161:
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;
59 break;
61 case AT45DB321:
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;
71 break;
73 case AT45DB642:
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;
83 break;
84 case AT45DB128:
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;
94 break;
96 default:
97 printf("\n\rflash nb %d not found",i);
98 break;
101 printf("\n\r");
102 AT91F_InitSdram();
103 return (1);
106 int get_size_reg()
108 if ((dataflash_info[2].id != 0) && (dataflash_info[3].id != 0 )){
109 return SIZE_REGS_128M;
111 else {
112 return SIZE_REGS_64M;
116 void AT91F_DataflashPrintInfo(void)
118 int i;
119 int *pregister;
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
126 case AT45DB161:
127 printf ("AT45DB161\n\r");
128 break;
130 case AT45DB321:
131 printf ("AT45DB321\n\r");
132 break;
133 #endif
134 case AT45DB642:
135 printf ("AT45DB642\n\r");
136 break;
137 case AT45DB128:
138 printf ("AT45DB128\n\r");
139 break;
142 printf ("Nb pages: %6d\n\r"
143 "Page Size: %6d\n\r"
144 "Size=%8d bytes\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,
161 unsigned int *addr)
163 char addr_valid = 0;
164 int i;
166 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
167 if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) {
168 addr_valid = 1;
169 break;
171 if (!addr_valid) {
172 pFlash = (AT91PS_DataFlash) 0;
173 return pFlash;
175 pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
176 pFlash->pDevice = &(dataflash_info[i].Device);
177 *addr -= dataflash_info[i].logical_address;
178 return (pFlash);
182 /*------------------------------------------------------------------------------*/
183 /* Function Name : addr_dataflash */
184 /* Object : Test if address is valid */
185 /*------------------------------------------------------------------------------*/
186 int addr_dataflash (unsigned long addr)
188 int addr_valid = 0;
189 int i;
191 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
192 if ((((int) addr) & 0xFF000000) ==
193 dataflash_info[i].logical_address) {
194 addr_valid = 1;
195 break;
199 return addr_valid;
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);
213 if (pFlash == 0)
214 return -1;
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,
225 unsigned int size)
227 unsigned int AddrToWrite = addr_dest;
228 AT91PS_DataFlash pFlash = &DataFlashInst;
230 pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
231 if (AddrToWrite == -1)
232 return -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;
242 int page_nb;
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);
254 if (!status) {
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
267 * a protéger.
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
286 * et désactivée par
288 * Disable Sector Protection 3DH 2AH 7FH 9AH
291 static void clear_desc( AT91S_DataflashDesc *d)
293 #ifdef REDUCE_CODE_SIZE
294 int i;
295 char *ptr1 = ( char *)d;
296 for ( i = 0 ; i < sizeof(AT91S_DataflashDesc) ; i++)
298 *ptr1 = 0;
299 ptr1++;
302 #else
303 d->tx_cmd_pt = 0;
304 d->rx_cmd_pt = 0;
305 d->tx_cmd_size = 0;
306 d->rx_cmd_size = 0;
307 d->tx_data_size = 0;
308 d->rx_data_size = 0;
309 d->tx_data_pt = 0;
310 d->rx_data_pt = 0;
311 d->state = 0;
312 d->DataFlash_state = 0;
313 d->command[0] = 0;
314 d->command[1] = 0;
315 d->command[2] = 0;
316 d->command[3] = 0;
317 d->command[4] = 0;
318 d->command[5] = 0;
319 d->command[6] = 0;
320 d->command[7] = 0;
321 #endif
325 void memset(unsigned char *ptr,char val , int size)
327 int i;
328 for ( i = 0 ; i < size ; i++) {
329 *ptr = val;
330 ptr++;
333 AT91S_DataflashDesc desc;
335 t_read_lock_cmd read_lock_cmd_sector =
338 0x32,0x00,0x00,0x00
344 t_read_lock_cmd read_lock_cmd_lockdown=
347 0x35,0x00,0x00,0x00
353 t_read_lock_cmd read_lock_cmd_security=
356 0x77,0x00,0x00,0x00
358 128,
362 void AT91F_SpiEnable(int cs);
364 void read_lock_reg(t_read_lock_cmd *ptrcmd)
366 int i;
367 unsigned char rx[129];
368 char *ptr;
369 int fl_nb;
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]);
376 clear_desc(&desc);
377 memset(rx,0,sizeof(rx));
378 rx[0] = 8;
379 desc.tx_cmd_pt = ptrcmd->cmd;
380 desc.rx_cmd_pt = rx;
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);
389 printf("\n\r");
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++ ) {
401 if ((i % 16) == 0) {
402 printf("\n\r");
404 printf("0x%02x:",rx[i]);
406 printf("\n\r");
412 unsigned char clear_lock_cmd[4]=
414 0x3D,0x2A,0x7F,0xCF
417 void clear_lock_reg()
419 int i;
420 unsigned char rx[33];
421 int fl_nb;
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]);
429 clear_desc(&desc);
431 desc.tx_cmd_pt = clear_lock_cmd;
432 desc.rx_cmd_pt = rx;
433 desc.tx_cmd_size = 4;
434 desc.rx_cmd_size = 4;
435 AT91F_SpiWrite(&desc);
440 unsigned char lock_unlock_cmd[4]=
442 0x3D,0x2A,0x7F,0xFC
445 unsigned char enable_lock_unlock_cmd[4]=
447 0x3D,0x2A,0x7F,0xA9
450 unsigned char disable_lock_unlock_cmd[4]=
452 0x3D,0x2A,0x7F,0x9A
456 void flash_en_lock_unlock(unsigned char *cmd)
458 unsigned char rxf[4];
459 unsigned char rx[33];
460 clear_desc(&desc);
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));
476 clear_desc(&desc);
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()
491 int i;
492 int fl_nb;
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()
506 int i;
508 int fl_nb;
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);