OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 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 : at45c.h |
||
11 | * Object : |
||
12 | * |
||
13 | * 1.0 10/12/03 HIi : Creation. |
||
14 | * 1.01 03/05/04 HIi : Bug Fix in AT91F_DataFlashWaitReady() Function. |
||
15 | *---------------------------------------------------------------------------- |
||
16 | */ |
||
17 | #include "config.h" |
||
18 | #include "stdio.h" |
||
19 | #include "AT91RM9200.h" |
||
20 | #include "lib_AT91RM9200.h" |
||
21 | #include "dataflash.h" |
||
22 | #include "main.h" |
||
23 | |||
24 | |||
25 | /*----------------------------------------------------------------------------*/ |
||
26 | /* \fn AT91F_SpiInit */ |
||
27 | /* \brief SPI Low level Init */ |
||
28 | /*----------------------------------------------------------------------------*/ |
||
29 | void AT91F_SpiInit(void) { |
||
30 | /* Configure PIOs */ |
||
31 | AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | |
||
32 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 | |
||
33 | AT91C_PA6_NPCS3 | AT91C_PA0_MISO | |
||
34 | AT91C_PA2_SPCK; |
||
35 | AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | |
||
36 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 | |
||
37 | AT91C_PA6_NPCS3 | AT91C_PA0_MISO | |
||
38 | AT91C_PA2_SPCK; |
||
39 | /* Enable CLock */ |
||
40 | AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI; |
||
41 | |||
42 | /* Reset the SPI */ |
||
43 | AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; |
||
44 | |||
45 | /* Configure SPI in Master Mode with No CS selected !!! */ |
||
46 | AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS; |
||
47 | |||
48 | /* Configure CS0 and CS3 */ |
||
49 | *(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | |
||
50 | (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | |
||
51 | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); |
||
52 | *(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | |
||
53 | (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | |
||
54 | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); |
||
55 | } |
||
56 | |||
57 | |||
58 | /*----------------------------------------------------------------------------*/ |
||
59 | /* \fn AT91F_SpiEnable */ |
||
60 | /* \brief Enable SPI chip select */ |
||
61 | /*----------------------------------------------------------------------------*/ |
||
62 | static void AT91F_SpiEnable(int cs) { |
||
63 | switch(cs) { |
||
64 | case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */ |
||
65 | AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; |
||
66 | AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH << 16) & AT91C_SPI_PCS); |
||
67 | break; |
||
68 | case 3: /* Configure SPI CS3 for Serial DataFlash Card */ |
||
69 | /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */ |
||
70 | AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */ |
||
71 | AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */ |
||
72 | /* Clear Output */ |
||
73 | AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7; |
||
74 | /* Configure PCS */ |
||
75 | AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; |
||
76 | AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS); |
||
77 | break; |
||
78 | } |
||
79 | |||
80 | /* SPI_Enable */ |
||
81 | AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; |
||
82 | } |
||
83 | |||
84 | /*----------------------------------------------------------------------------*/ |
||
85 | /* \fn AT91F_SpiWrite */ |
||
86 | /* \brief Set the PDC registers for a transfert */ |
||
87 | /*----------------------------------------------------------------------------*/ |
||
88 | static unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc) |
||
89 | { |
||
90 | unsigned int timeout; |
||
91 | |||
92 | AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; |
||
93 | |||
94 | /* Initialize the Transmit and Receive Pointer */ |
||
95 | AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ; |
||
96 | AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ; |
||
97 | |||
98 | /* Intialize the Transmit and Receive Counters */ |
||
99 | AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size; |
||
100 | AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size; |
||
101 | |||
102 | if ( pDesc->tx_data_size != 0 ) { |
||
103 | /* Initialize the Next Transmit and Next Receive Pointer */ |
||
104 | AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ; |
||
105 | AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ; |
||
106 | |||
107 | /* Intialize the Next Transmit and Next Receive Counters */ |
||
108 | AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ; |
||
109 | AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ; |
||
110 | } |
||
111 | |||
112 | /* ARM simple, non interrupt dependent timer */ |
||
113 | timeout = 0; |
||
114 | |||
115 | AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN; |
||
116 | while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF)); |
||
117 | |||
118 | AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; |
||
119 | |||
120 | if (timeout >= AT91C_DATAFLASH_TIMEOUT){ |
||
121 | return AT91C_DATAFLASH_ERROR; |
||
122 | } |
||
123 | |||
124 | return AT91C_DATAFLASH_OK; |
||
125 | } |
||
126 | |||
127 | |||
128 | /*----------------------------------------------------------------------*/ |
||
129 | /* \fn AT91F_DataFlashSendCommand */ |
||
130 | /* \brief Generic function to send a command to the dataflash */ |
||
131 | /*----------------------------------------------------------------------*/ |
||
132 | static AT91S_DataFlashStatus AT91F_DataFlashSendCommand( |
||
133 | AT91PS_DataFlash pDataFlash, |
||
134 | unsigned char OpCode, |
||
135 | unsigned int CmdSize, |
||
136 | unsigned int DataflashAddress) |
||
137 | { |
||
138 | unsigned int adr; |
||
139 | |||
140 | /* process the address to obtain page address and byte address */ |
||
141 | adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) |
||
142 | << pDataFlash->pDevice->page_offset) + |
||
143 | (DataflashAddress % (pDataFlash->pDevice->pages_size)); |
||
144 | |||
145 | /* fill the command buffer */ |
||
146 | pDataFlash->pDataFlashDesc->command[0] = OpCode; |
||
147 | if (pDataFlash->pDevice->pages_number >= 16384) |
||
148 | { |
||
149 | pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24); |
||
150 | pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16); |
||
151 | pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8); |
||
152 | pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF); |
||
153 | } |
||
154 | else |
||
155 | { |
||
156 | pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16); |
||
157 | pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8); |
||
158 | pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ; |
||
159 | pDataFlash->pDataFlashDesc->command[4] = 0; |
||
160 | } |
||
161 | pDataFlash->pDataFlashDesc->command[5] = 0; |
||
162 | pDataFlash->pDataFlashDesc->command[6] = 0; |
||
163 | pDataFlash->pDataFlashDesc->command[7] = 0; |
||
164 | |||
165 | /* Initialize the SpiData structure for the spi write fuction */ |
||
166 | pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ; |
||
167 | pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ; |
||
168 | pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ; |
||
169 | pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ; |
||
170 | |||
171 | return AT91F_SpiWrite(pDataFlash->pDataFlashDesc); |
||
172 | } |
||
173 | |||
174 | |||
175 | /*----------------------------------------------------------------------*/ |
||
176 | /* \fn AT91F_DataFlashGetStatus */ |
||
177 | /* \brief Read the status register of the dataflash */ |
||
178 | /*----------------------------------------------------------------------*/ |
||
179 | static AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc) |
||
180 | { |
||
181 | AT91S_DataFlashStatus status; |
||
182 | |||
183 | /* first send the read status command (D7H) */ |
||
184 | pDesc->command[0] = DB_STATUS; |
||
185 | pDesc->command[1] = 0; |
||
186 | |||
187 | pDesc->DataFlash_state = GET_STATUS; |
||
188 | pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */ |
||
189 | pDesc->tx_cmd_pt = pDesc->command ; |
||
190 | pDesc->rx_cmd_pt = pDesc->command ; |
||
191 | pDesc->rx_cmd_size = 2 ; |
||
192 | pDesc->tx_cmd_size = 2 ; |
||
193 | status = AT91F_SpiWrite (pDesc); |
||
194 | |||
195 | pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1); |
||
196 | return status; |
||
197 | } |
||
198 | |||
199 | /*----------------------------------------------------------------------------- |
||
200 | * Function Name : AT91F_DataFlashWaitReady |
||
201 | * Object : wait for dataflash ready (bit7 of the status register == 1) |
||
202 | * Input Parameters : DataFlash Service and timeout |
||
203 | * Return value : DataFlash status "ready or not" |
||
204 | *----------------------------------------------------------------------------- |
||
205 | */ |
||
206 | static AT91S_DataFlashStatus AT91F_DataFlashWaitReady( |
||
207 | AT91PS_DataflashDesc pDataFlashDesc, |
||
208 | unsigned int timeout) |
||
209 | { |
||
210 | pDataFlashDesc->DataFlash_state = IDLE; |
||
211 | do { |
||
212 | AT91F_DataFlashGetStatus(pDataFlashDesc); |
||
213 | timeout--; |
||
214 | } |
||
215 | while(((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0)); |
||
216 | |||
217 | if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) |
||
218 | return AT91C_DATAFLASH_ERROR; |
||
219 | |||
220 | return AT91C_DATAFLASH_OK; |
||
221 | } |
||
222 | |||
223 | |||
224 | /*------------------------------------------------------------------------------*/ |
||
225 | /* Function Name : AT91F_DataFlashContinuousRead */ |
||
226 | /* Object : Continuous stream Read */ |
||
227 | /* Input Parameters : DataFlash Service */ |
||
228 | /* : <src> = dataflash address */ |
||
229 | /* : <*dataBuffer> = data buffer pointer */ |
||
230 | /* : <sizeToRead> = data buffer size */ |
||
231 | /* Return value : State of the dataflash */ |
||
232 | /*------------------------------------------------------------------------------*/ |
||
233 | static AT91S_DataFlashStatus AT91F_DataFlashContinuousRead( |
||
234 | AT91PS_DataFlash pDataFlash, |
||
235 | int src, |
||
236 | unsigned char *dataBuffer, |
||
237 | int sizeToRead ) |
||
238 | { |
||
239 | AT91S_DataFlashStatus status; |
||
240 | /* Test the size to read in the device */ |
||
241 | if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number))) |
||
242 | return AT91C_DATAFLASH_MEMORY_OVERFLOW; |
||
243 | |||
244 | pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer; |
||
245 | pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead; |
||
246 | pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer; |
||
247 | pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead; |
||
248 | |||
249 | status = AT91F_DataFlashSendCommand(pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src); |
||
250 | /* Send the command to the dataflash */ |
||
251 | return(status); |
||
252 | } |
||
253 | |||
254 | |||
255 | |||
256 | /*------------------------------------------------------------------------------*/ |
||
257 | /* Function Name : AT91F_MainMemoryToBufferTransfer */ |
||
258 | /* Object : Read a page in the SRAM Buffer 1 or 2 */ |
||
259 | /* Input Parameters : DataFlash Service */ |
||
260 | /* : Page concerned */ |
||
261 | /* : */ |
||
262 | /* Return value : State of the dataflash */ |
||
263 | /*------------------------------------------------------------------------------*/ |
||
264 | static AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfer( |
||
265 | AT91PS_DataFlash pDataFlash, |
||
266 | unsigned char BufferCommand, |
||
267 | unsigned int page) |
||
268 | { |
||
269 | int cmdsize; |
||
270 | /* Test if the buffer command is legal */ |
||
271 | if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF)) |
||
272 | return AT91C_DATAFLASH_BAD_COMMAND; |
||
273 | |||
274 | /* no data to transmit or receive */ |
||
275 | pDataFlash->pDataFlashDesc->tx_data_size = 0; |
||
276 | cmdsize = 4; |
||
277 | if (pDataFlash->pDevice->pages_number >= 16384) |
||
278 | cmdsize = 5; |
||
279 | return(AT91F_DataFlashSendCommand(pDataFlash, BufferCommand, cmdsize, |
||
280 | page*pDataFlash->pDevice->pages_size)); |
||
281 | } |
||
282 | |||
283 | |||
284 | |||
285 | /*----------------------------------------------------------------------------- */ |
||
286 | /* Function Name : AT91F_DataFlashWriteBuffer */ |
||
287 | /* Object : Write data to the internal sram buffer 1 or 2 */ |
||
288 | /* Input Parameters : DataFlash Service */ |
||
289 | /* : <BufferCommand> = command to write buffer1 or buffer2 */ |
||
290 | /* : <*dataBuffer> = data buffer to write */ |
||
291 | /* : <bufferAddress> = address in the internal buffer */ |
||
292 | /* : <SizeToWrite> = data buffer size */ |
||
293 | /* Return value : State of the dataflash */ |
||
294 | /*------------------------------------------------------------------------------*/ |
||
295 | static AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer( |
||
296 | AT91PS_DataFlash pDataFlash, |
||
297 | unsigned char BufferCommand, |
||
298 | unsigned char *dataBuffer, |
||
299 | unsigned int bufferAddress, |
||
300 | int SizeToWrite ) |
||
301 | { |
||
302 | int cmdsize; |
||
303 | /* Test if the buffer command is legal */ |
||
304 | if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE)) |
||
305 | return AT91C_DATAFLASH_BAD_COMMAND; |
||
306 | |||
307 | /* buffer address must be lower than page size */ |
||
308 | if (bufferAddress > pDataFlash->pDevice->pages_size) |
||
309 | return AT91C_DATAFLASH_BAD_ADDRESS; |
||
310 | |||
311 | /* Send first Write Command */ |
||
312 | pDataFlash->pDataFlashDesc->command[0] = BufferCommand; |
||
313 | pDataFlash->pDataFlashDesc->command[1] = 0; |
||
314 | if (pDataFlash->pDevice->pages_number >= 16384) |
||
315 | { |
||
316 | pDataFlash->pDataFlashDesc->command[2] = 0; |
||
317 | pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ; |
||
318 | pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ; |
||
319 | cmdsize = 5; |
||
320 | } |
||
321 | else |
||
322 | { |
||
323 | pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ; |
||
324 | pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ; |
||
325 | pDataFlash->pDataFlashDesc->command[4] = 0; |
||
326 | cmdsize = 4; |
||
327 | } |
||
328 | |||
329 | pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ; |
||
330 | pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ; |
||
331 | pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ; |
||
332 | pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ; |
||
333 | |||
334 | pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ; |
||
335 | pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ; |
||
336 | pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ; |
||
337 | pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ; |
||
338 | |||
339 | return AT91F_SpiWrite(pDataFlash->pDataFlashDesc); |
||
340 | } |
||
341 | |||
342 | |||
343 | /*------------------------------------------------------------------------------*/ |
||
344 | /* Function Name : AT91F_PageErase */ |
||
345 | /* Object : Read a page in the SRAM Buffer 1 or 2 */ |
||
346 | /* Input Parameters : DataFlash Service */ |
||
347 | /* : Page concerned */ |
||
348 | /* : */ |
||
349 | /* Return value : State of the dataflash */ |
||
350 | /*------------------------------------------------------------------------------*/ |
||
351 | static AT91S_DataFlashStatus AT91F_PageErase( |
||
352 | AT91PS_DataFlash pDataFlash, |
||
353 | unsigned int page) |
||
354 | { |
||
355 | int cmdsize; |
||
356 | /* Test if the buffer command is legal */ |
||
357 | /* no data to transmit or receive */ |
||
358 | pDataFlash->pDataFlashDesc->tx_data_size = 0; |
||
359 | |||
360 | cmdsize = 4; |
||
361 | if (pDataFlash->pDevice->pages_number >= 16384) |
||
362 | cmdsize = 5; |
||
363 | return(AT91F_DataFlashSendCommand(pDataFlash, DB_PAGE_ERASE, cmdsize, |
||
364 | page*pDataFlash->pDevice->pages_size)); |
||
365 | } |
||
366 | |||
367 | |||
368 | /*------------------------------------------------------------------------------*/ |
||
369 | /* Function Name : AT91F_WriteBufferToMain */ |
||
370 | /* Object : Write buffer to the main memory */ |
||
371 | /* Input Parameters : DataFlash Service */ |
||
372 | /* : <BufferCommand> = command to send to buf1 or buf2 */ |
||
373 | /* : <dest> = main memory address */ |
||
374 | /* Return value : State of the dataflash */ |
||
375 | /*------------------------------------------------------------------------------*/ |
||
376 | static AT91S_DataFlashStatus AT91F_WriteBufferToMain ( |
||
377 | AT91PS_DataFlash pDataFlash, |
||
378 | unsigned char BufferCommand, |
||
379 | unsigned int dest ) |
||
380 | { |
||
381 | int cmdsize; |
||
382 | /* Test if the buffer command is correct */ |
||
383 | if ((BufferCommand != DB_BUF1_PAGE_PGM) && |
||
384 | (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) && |
||
385 | (BufferCommand != DB_BUF2_PAGE_PGM) && |
||
386 | (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) ) |
||
387 | return AT91C_DATAFLASH_BAD_COMMAND; |
||
388 | |||
389 | /* no data to transmit or receive */ |
||
390 | pDataFlash->pDataFlashDesc->tx_data_size = 0; |
||
391 | |||
392 | cmdsize = 4; |
||
393 | if (pDataFlash->pDevice->pages_number >= 16384) |
||
394 | cmdsize = 5; |
||
395 | /* Send the command to the dataflash */ |
||
396 | return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest)); |
||
397 | } |
||
398 | |||
399 | |||
400 | /*------------------------------------------------------------------------------*/ |
||
401 | /* Function Name : AT91F_PartialPageWrite */ |
||
402 | /* Object : Erase partially a page */ |
||
403 | /* Input Parameters : <page> = page number */ |
||
404 | /* : <AdrInpage> = adr to begin the fading */ |
||
405 | /* : <length> = Number of bytes to erase */ |
||
406 | /*------------------------------------------------------------------------------*/ |
||
407 | static AT91S_DataFlashStatus AT91F_PartialPageWrite ( |
||
408 | AT91PS_DataFlash pDataFlash, |
||
409 | unsigned char *src, |
||
410 | unsigned int dest, |
||
411 | unsigned int size) |
||
412 | { |
||
413 | unsigned int page; |
||
414 | unsigned int AdrInPage; |
||
415 | |||
416 | page = dest / (pDataFlash->pDevice->pages_size); |
||
417 | AdrInPage = dest % (pDataFlash->pDevice->pages_size); |
||
418 | |||
419 | /* Read the contents of the page in the Sram Buffer */ |
||
420 | AT91F_MainMemoryToBufferTransfer(pDataFlash, DB_PAGE_2_BUF1_TRF, page); |
||
421 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
422 | |||
423 | /*Update the SRAM buffer */ |
||
424 | AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size); |
||
425 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
426 | |||
427 | /* Erase page if a 128 Mbits device */ |
||
428 | if (pDataFlash->pDevice->pages_number >= 16384) |
||
429 | { |
||
430 | AT91F_PageErase(pDataFlash, page); |
||
431 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
432 | } |
||
433 | |||
434 | /* Rewrite the modified Sram Buffer in the main memory */ |
||
435 | return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, |
||
436 | (page*pDataFlash->pDevice->pages_size))); |
||
437 | } |
||
438 | |||
439 | |||
440 | /*------------------------------------------------------------------------------*/ |
||
441 | /* Function Name : AT91F_DataFlashWrite */ |
||
442 | /* Object : */ |
||
443 | /* Input Parameters : <*src> = Source buffer */ |
||
444 | /* : <dest> = dataflash adress */ |
||
445 | /* : <size> = data buffer size */ |
||
446 | /*------------------------------------------------------------------------------*/ |
||
447 | AT91S_DataFlashStatus AT91F_DataFlashWrite( |
||
448 | AT91PS_DataFlash pDataFlash, |
||
449 | unsigned char *src, |
||
450 | int dest, |
||
451 | int size ) |
||
452 | { |
||
453 | unsigned int length; |
||
454 | unsigned int page; |
||
455 | unsigned int status; |
||
456 | |||
457 | AT91F_SpiEnable(pDataFlash->pDevice->cs); |
||
458 | |||
459 | if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number))) |
||
460 | return AT91C_DATAFLASH_MEMORY_OVERFLOW; |
||
461 | |||
462 | /* If destination does not fit a page start address */ |
||
463 | if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) { |
||
464 | length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size))); |
||
465 | |||
466 | if (size < length) |
||
467 | length = size; |
||
468 | |||
469 | if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length)) |
||
470 | return AT91C_DATAFLASH_ERROR; |
||
471 | |||
472 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
473 | |||
474 | /* Update size, source and destination pointers */ |
||
475 | size -= length; |
||
476 | dest += length; |
||
477 | src += length; |
||
478 | } |
||
479 | |||
480 | while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) |
||
481 | { |
||
482 | /* program dataflash page */ |
||
483 | page = (unsigned int)dest / (pDataFlash->pDevice->pages_size); |
||
484 | |||
485 | status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, |
||
486 | 0, pDataFlash->pDevice->pages_size); |
||
487 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
488 | |||
489 | status = AT91F_PageErase(pDataFlash, page); |
||
490 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
491 | if (!status) |
||
492 | return AT91C_DATAFLASH_ERROR; |
||
493 | |||
494 | status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest); |
||
495 | if(!status) |
||
496 | return AT91C_DATAFLASH_ERROR; |
||
497 | |||
498 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
499 | |||
500 | /* Update size, source and destination pointers */ |
||
501 | size -= pDataFlash->pDevice->pages_size ; |
||
502 | dest += pDataFlash->pDevice->pages_size ; |
||
503 | src += pDataFlash->pDevice->pages_size ; |
||
504 | } |
||
505 | |||
506 | /* If still some bytes to read */ |
||
507 | if ( size > 0 ) { |
||
508 | /* program dataflash page */ |
||
509 | if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) ) |
||
510 | return AT91C_DATAFLASH_ERROR; |
||
511 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
512 | } |
||
513 | return AT91C_DATAFLASH_OK; |
||
514 | } |
||
515 | |||
516 | |||
517 | /*------------------------------------------------------------------------------*/ |
||
518 | /* Function Name : AT91F_DataFlashRead */ |
||
519 | /* Object : Read a block in dataflash */ |
||
520 | /* Input Parameters : */ |
||
521 | /* Return value : */ |
||
522 | /*------------------------------------------------------------------------------*/ |
||
523 | int AT91F_DataFlashRead( |
||
524 | AT91PS_DataFlash pDataFlash, |
||
525 | unsigned long addr, |
||
526 | unsigned long size, |
||
527 | char *buffer) |
||
528 | { |
||
529 | unsigned long SizeToRead; |
||
530 | |||
531 | AT91F_SpiEnable(pDataFlash->pDevice->cs); |
||
532 | |||
533 | if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK) |
||
534 | return -1; |
||
535 | |||
536 | while (size) |
||
537 | { |
||
538 | SizeToRead = (size < 0x8000)? size:0x8000; |
||
539 | |||
540 | if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) |
||
541 | != AT91C_DATAFLASH_OK) |
||
542 | return -1; |
||
543 | |||
544 | if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (unsigned char *)buffer, |
||
545 | SizeToRead) != AT91C_DATAFLASH_OK) |
||
546 | return -1; |
||
547 | |||
548 | size -= SizeToRead; |
||
549 | addr += SizeToRead; |
||
550 | buffer += SizeToRead; |
||
551 | } |
||
552 | |||
553 | return AT91C_DATAFLASH_OK; |
||
554 | } |
||
555 | |||
556 | |||
557 | /*------------------------------------------------------------------------------*/ |
||
558 | /* Function Name : AT91F_DataflashProbe */ |
||
559 | /* Object : */ |
||
560 | /* Input Parameters : */ |
||
561 | /* Return value : Dataflash status register */ |
||
562 | /*------------------------------------------------------------------------------*/ |
||
563 | int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc) |
||
564 | { |
||
565 | AT91F_SpiEnable(cs); |
||
566 | AT91F_DataFlashGetStatus(pDesc); |
||
567 | return ((pDesc->command[1] == 0xFF)? 0: (pDesc->command[1] & 0x3C)); |
||
568 | } |
||
569 | |||
570 | /*------------------------------------------------------------------------------*/ |
||
571 | /* Function Name : AT91F_DataFlashErase */ |
||
572 | /* Object : */ |
||
573 | /* Input Parameters : <*pDataFlash> = Device info */ |
||
574 | /*------------------------------------------------------------------------------*/ |
||
575 | AT91S_DataFlashStatus AT91F_DataFlashErase(AT91PS_DataFlash pDataFlash) |
||
576 | { |
||
577 | unsigned int page; |
||
578 | unsigned int status; |
||
579 | |||
580 | AT91F_SpiEnable(pDataFlash->pDevice->cs); |
||
581 | |||
582 | for(page=0; page < pDataFlash->pDevice->pages_number; page++) |
||
583 | { |
||
584 | /* Erase dataflash page */ |
||
585 | if ((page & 0x00FF) == 0) |
||
586 | printf("\rERA %d/%d", page, pDataFlash->pDevice->pages_number); |
||
587 | status = AT91F_PageErase(pDataFlash, page); |
||
588 | AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); |
||
589 | if (!status) |
||
590 | return AT91C_DATAFLASH_ERROR; |
||
591 | } |
||
592 | |||
593 | return AT91C_DATAFLASH_OK; |
||
594 | } |
||
595 |