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 *----------------------------------------------------------------------------
14 */
15#include "config.h"
16#include "stdio.h"
17#include "dataflash.h"
18
19
20AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS];
21static AT91S_DataFlash DataFlashInst;
22
23int cs[][CFG_MAX_DATAFLASH_BANKS] = {
24	{CFG_DATAFLASH_LOGIC_ADDR_CS0, 0},	/* Logical adress, CS */
25	{CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
26};
27
28int AT91F_DataflashInit(void)
29{
30	int i;
31	int dfcode;
32	int Nb_device = 0;
33
34	AT91F_SpiInit();
35
36	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
37		dataflash_info[i].id = 0;
38		dataflash_info[i].Device.pages_number = 0;
39		dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc);
40
41		switch (dfcode) {
42		case AT45DB161:
43			dataflash_info[i].Device.pages_number = 4096;
44			dataflash_info[i].Device.pages_size = 528;
45			dataflash_info[i].Device.page_offset = 10;
46			dataflash_info[i].Device.byte_mask = 0x300;
47			dataflash_info[i].Device.cs = cs[i][1];
48			dataflash_info[i].Desc.DataFlash_state = IDLE;
49			dataflash_info[i].logical_address = cs[i][0];
50			dataflash_info[i].id = dfcode;
51			Nb_device++;
52			break;
53
54		case AT45DB321:
55			dataflash_info[i].Device.pages_number = 8192;
56			dataflash_info[i].Device.pages_size = 528;
57			dataflash_info[i].Device.page_offset = 10;
58			dataflash_info[i].Device.byte_mask = 0x300;
59			dataflash_info[i].Device.cs = cs[i][1];
60			dataflash_info[i].Desc.DataFlash_state = IDLE;
61			dataflash_info[i].logical_address = cs[i][0];
62			dataflash_info[i].id = dfcode;
63			Nb_device++;
64			break;
65
66		case AT45DB642:
67			dataflash_info[i].Device.pages_number = 8192;
68			dataflash_info[i].Device.pages_size = 1056;
69			dataflash_info[i].Device.page_offset = 11;
70			dataflash_info[i].Device.byte_mask = 0x700;
71			dataflash_info[i].Device.cs = cs[i][1];
72			dataflash_info[i].Desc.DataFlash_state = IDLE;
73			dataflash_info[i].logical_address = cs[i][0];
74			dataflash_info[i].id = dfcode;
75			Nb_device++;
76			break;
77		case AT45DB128:
78			dataflash_info[i].Device.pages_number = 16384;
79			dataflash_info[i].Device.pages_size = 1056;
80			dataflash_info[i].Device.page_offset = 11;
81			dataflash_info[i].Device.byte_mask = 0x700;
82			dataflash_info[i].Device.cs = cs[i][1];
83			dataflash_info[i].Desc.DataFlash_state = IDLE;
84			dataflash_info[i].logical_address = cs[i][0];
85			dataflash_info[i].id = dfcode;
86			Nb_device++;
87			break;
88		default:
89			break;
90		}
91	}
92	return (Nb_device);
93}
94
95
96void AT91F_DataflashPrintInfo(void)
97{
98	int i;
99	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
100		if (dataflash_info[i].id != 0) {
101			printf ("DF:AT45DB");
102			switch (dataflash_info[i].id) {
103			case AT45DB161:
104				printf ("161");
105				break;
106
107			case AT45DB321:
108				printf ("321");
109				break;
110
111			case AT45DB642:
112				printf ("642");
113				break;
114			case AT45DB128:
115				printf ("128");
116				break;
117			}
118
119			printf ("\n# PG: %6d\n"
120				"PG SZ: %6d\n"
121				"SZ=%8d bytes\n"
122				"ADDR: %08X\n",
123				(unsigned int) dataflash_info[i].Device.pages_number,
124				(unsigned int) dataflash_info[i].Device.pages_size,
125				(unsigned int) dataflash_info[i].Device.pages_number *
126				dataflash_info[i].Device.pages_size,
127				(unsigned int) dataflash_info[i].logical_address);
128		}
129	}
130}
131
132
133/*------------------------------------------------------------------------------*/
134/* Function Name       : AT91F_DataflashSelect                                  */
135/* Object              : Select the correct device                              */
136/*------------------------------------------------------------------------------*/
137static AT91PS_DataFlash AT91F_DataflashSelect(AT91PS_DataFlash pFlash,
138                                              unsigned int *addr)
139{
140	char addr_valid = 0;
141	int i;
142
143	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
144		if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) {
145			addr_valid = 1;
146			break;
147		}
148	if (!addr_valid) {
149		pFlash = (AT91PS_DataFlash) 0;
150		return pFlash;
151	}
152	pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
153	pFlash->pDevice = &(dataflash_info[i].Device);
154	*addr -= dataflash_info[i].logical_address;
155	return (pFlash);
156}
157
158
159/*------------------------------------------------------------------------------*/
160/* Function Name       : read_dataflash                                         */
161/* Object              : dataflash memory read                                  */
162/*------------------------------------------------------------------------------*/
163int read_dataflash(unsigned long addr, unsigned long size, char *result)
164{
165	unsigned int AddrToRead = addr;
166	AT91PS_DataFlash pFlash = &DataFlashInst;
167
168	pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
169	if (pFlash == 0)
170		return -1;
171
172	return (AT91F_DataFlashRead(pFlash, AddrToRead, size, result));
173}
174
175
176/*-----------------------------------------------------------------------------*/
177/* Function Name       : write_dataflash                                       */
178/* Object              : write a block in dataflash                            */
179/*-----------------------------------------------------------------------------*/
180int write_dataflash(unsigned long addr_dest, unsigned int addr_src,
181                    unsigned int size)
182{
183	unsigned int AddrToWrite = addr_dest;
184	AT91PS_DataFlash pFlash = &DataFlashInst;
185
186	pFlash = AT91F_DataflashSelect(pFlash, &AddrToWrite);
187	if (AddrToWrite == -1)
188		return -1;
189
190	return AT91F_DataFlashWrite(pFlash, (unsigned char *) addr_src, AddrToWrite, size);
191}
192
193/*-----------------------------------------------------------------------------*/
194/* Function Name       : erase_dataflash                                       */
195/* Object              : Erase entire dataflash                                */
196/*-----------------------------------------------------------------------------*/
197int erase_dataflash(unsigned long addr_dest)
198{
199	unsigned int AddrToWrite = addr_dest;
200	AT91PS_DataFlash pFlash = &DataFlashInst;
201
202	pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
203	if (AddrToWrite == -1)
204		return -1;
205
206	return AT91F_DataFlashErase(pFlash);
207}
208
209