]> git.gir.st - tmk_keyboard.git/blob - protocol/lufa/LUFA-git/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c
Squashed 'tmk_core/' changes from d5c5ac6..8da1898
[tmk_keyboard.git] / protocol / lufa / LUFA-git / Demos / Device / LowLevel / MassStorage / Lib / DataflashManager.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2014.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.lufa-lib.org
7 */
8
9 /*
10 Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, distribute, and sell this
13 software and its documentation for any purpose is hereby granted
14 without fee, provided that the above copyright notice appear in
15 all copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaims all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 /** \file
32 *
33 * Functions to manage the physical Dataflash media, including reading and writing of
34 * blocks of data. These functions are called by the SCSI layer when data must be stored
35 * or retrieved to/from the physical storage media. If a different media is used (such
36 * as a SD card or EEPROM), functions similar to these will need to be generated.
37 */
38
39 #define INCLUDE_FROM_DATAFLASHMANAGER_C
40 #include "DataflashManager.h"
41
42 /** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board Dataflash IC(s), from
43 * the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes
44 * them to the Dataflash in Dataflash page sized blocks.
45 *
46 * \param[in] BlockAddress Data block starting address for the write sequence
47 * \param[in] TotalBlocks Number of blocks of data to write
48 */
49 void DataflashManager_WriteBlocks(const uint32_t BlockAddress,
50 uint16_t TotalBlocks)
51 {
52 uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
53 uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
54 uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
55 bool UsingSecondBuffer = false;
56
57 /* Select the correct starting Dataflash IC for the block requested */
58 Dataflash_SelectChipFromPage(CurrDFPage);
59
60 #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
61 /* Copy selected dataflash's current page contents to the Dataflash buffer */
62 Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
63 Dataflash_SendAddressBytes(CurrDFPage, 0);
64 Dataflash_WaitWhileBusy();
65 #endif
66
67 /* Send the Dataflash buffer write command */
68 Dataflash_SendByte(DF_CMD_BUFF1WRITE);
69 Dataflash_SendAddressBytes(0, CurrDFPageByte);
70
71 /* Wait until endpoint is ready before continuing */
72 if (Endpoint_WaitUntilReady())
73 return;
74
75 while (TotalBlocks)
76 {
77 uint8_t BytesInBlockDiv16 = 0;
78
79 /* Write an endpoint packet sized data block to the Dataflash */
80 while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
81 {
82 /* Check if the endpoint is currently empty */
83 if (!(Endpoint_IsReadWriteAllowed()))
84 {
85 /* Clear the current endpoint bank */
86 Endpoint_ClearOUT();
87
88 /* Wait until the host has sent another packet */
89 if (Endpoint_WaitUntilReady())
90 return;
91 }
92
93 /* Check if end of Dataflash page reached */
94 if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
95 {
96 /* Write the Dataflash buffer contents back to the Dataflash page */
97 Dataflash_WaitWhileBusy();
98 Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
99 Dataflash_SendAddressBytes(CurrDFPage, 0);
100
101 /* Reset the Dataflash buffer counter, increment the page counter */
102 CurrDFPageByteDiv16 = 0;
103 CurrDFPage++;
104
105 /* Once all the Dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
106 if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
107 UsingSecondBuffer = !(UsingSecondBuffer);
108
109 /* Select the next Dataflash chip based on the new Dataflash page index */
110 Dataflash_SelectChipFromPage(CurrDFPage);
111
112 #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
113 /* If less than one Dataflash page remaining, copy over the existing page to preserve trailing data */
114 if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
115 {
116 /* Copy selected dataflash's current page contents to the Dataflash buffer */
117 Dataflash_WaitWhileBusy();
118 Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
119 Dataflash_SendAddressBytes(CurrDFPage, 0);
120 Dataflash_WaitWhileBusy();
121 }
122 #endif
123
124 /* Send the Dataflash buffer write command */
125 Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
126 Dataflash_SendAddressBytes(0, 0);
127 }
128
129 /* Write one 16-byte chunk of data to the Dataflash */
130 Dataflash_SendByte(Endpoint_Read_8());
131 Dataflash_SendByte(Endpoint_Read_8());
132 Dataflash_SendByte(Endpoint_Read_8());
133 Dataflash_SendByte(Endpoint_Read_8());
134 Dataflash_SendByte(Endpoint_Read_8());
135 Dataflash_SendByte(Endpoint_Read_8());
136 Dataflash_SendByte(Endpoint_Read_8());
137 Dataflash_SendByte(Endpoint_Read_8());
138 Dataflash_SendByte(Endpoint_Read_8());
139 Dataflash_SendByte(Endpoint_Read_8());
140 Dataflash_SendByte(Endpoint_Read_8());
141 Dataflash_SendByte(Endpoint_Read_8());
142 Dataflash_SendByte(Endpoint_Read_8());
143 Dataflash_SendByte(Endpoint_Read_8());
144 Dataflash_SendByte(Endpoint_Read_8());
145 Dataflash_SendByte(Endpoint_Read_8());
146
147 /* Increment the Dataflash page 16 byte block counter */
148 CurrDFPageByteDiv16++;
149
150 /* Increment the block 16 byte block counter */
151 BytesInBlockDiv16++;
152
153 /* Check if the current command is being aborted by the host */
154 if (IsMassStoreReset)
155 return;
156 }
157
158 /* Decrement the blocks remaining counter */
159 TotalBlocks--;
160 }
161
162 /* Write the Dataflash buffer contents back to the Dataflash page */
163 Dataflash_WaitWhileBusy();
164 Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
165 Dataflash_SendAddressBytes(CurrDFPage, 0x00);
166 Dataflash_WaitWhileBusy();
167
168 /* If the endpoint is empty, clear it ready for the next packet from the host */
169 if (!(Endpoint_IsReadWriteAllowed()))
170 Endpoint_ClearOUT();
171
172 /* Deselect all Dataflash chips */
173 Dataflash_DeselectChip();
174 }
175
176 /** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board Dataflash IC(s), into
177 * the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash
178 * and writes them in OS sized blocks to the endpoint.
179 *
180 * \param[in] BlockAddress Data block starting address for the read sequence
181 * \param[in] TotalBlocks Number of blocks of data to read
182 */
183 void DataflashManager_ReadBlocks(const uint32_t BlockAddress,
184 uint16_t TotalBlocks)
185 {
186 uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
187 uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
188 uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
189
190 /* Select the correct starting Dataflash IC for the block requested */
191 Dataflash_SelectChipFromPage(CurrDFPage);
192
193 /* Send the Dataflash main memory page read command */
194 Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
195 Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
196 Dataflash_SendByte(0x00);
197 Dataflash_SendByte(0x00);
198 Dataflash_SendByte(0x00);
199 Dataflash_SendByte(0x00);
200
201 /* Wait until endpoint is ready before continuing */
202 if (Endpoint_WaitUntilReady())
203 return;
204
205 while (TotalBlocks)
206 {
207 uint8_t BytesInBlockDiv16 = 0;
208
209 /* Write an endpoint packet sized data block to the Dataflash */
210 while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
211 {
212 /* Check if the endpoint is currently full */
213 if (!(Endpoint_IsReadWriteAllowed()))
214 {
215 /* Clear the endpoint bank to send its contents to the host */
216 Endpoint_ClearIN();
217
218 /* Wait until the endpoint is ready for more data */
219 if (Endpoint_WaitUntilReady())
220 return;
221 }
222
223 /* Check if end of Dataflash page reached */
224 if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
225 {
226 /* Reset the Dataflash buffer counter, increment the page counter */
227 CurrDFPageByteDiv16 = 0;
228 CurrDFPage++;
229
230 /* Select the next Dataflash chip based on the new Dataflash page index */
231 Dataflash_SelectChipFromPage(CurrDFPage);
232
233 /* Send the Dataflash main memory page read command */
234 Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
235 Dataflash_SendAddressBytes(CurrDFPage, 0);
236 Dataflash_SendByte(0x00);
237 Dataflash_SendByte(0x00);
238 Dataflash_SendByte(0x00);
239 Dataflash_SendByte(0x00);
240 }
241
242 /* Read one 16-byte chunk of data from the Dataflash */
243 Endpoint_Write_8(Dataflash_ReceiveByte());
244 Endpoint_Write_8(Dataflash_ReceiveByte());
245 Endpoint_Write_8(Dataflash_ReceiveByte());
246 Endpoint_Write_8(Dataflash_ReceiveByte());
247 Endpoint_Write_8(Dataflash_ReceiveByte());
248 Endpoint_Write_8(Dataflash_ReceiveByte());
249 Endpoint_Write_8(Dataflash_ReceiveByte());
250 Endpoint_Write_8(Dataflash_ReceiveByte());
251 Endpoint_Write_8(Dataflash_ReceiveByte());
252 Endpoint_Write_8(Dataflash_ReceiveByte());
253 Endpoint_Write_8(Dataflash_ReceiveByte());
254 Endpoint_Write_8(Dataflash_ReceiveByte());
255 Endpoint_Write_8(Dataflash_ReceiveByte());
256 Endpoint_Write_8(Dataflash_ReceiveByte());
257 Endpoint_Write_8(Dataflash_ReceiveByte());
258 Endpoint_Write_8(Dataflash_ReceiveByte());
259
260 /* Increment the Dataflash page 16 byte block counter */
261 CurrDFPageByteDiv16++;
262
263 /* Increment the block 16 byte block counter */
264 BytesInBlockDiv16++;
265
266 /* Check if the current command is being aborted by the host */
267 if (IsMassStoreReset)
268 return;
269 }
270
271 /* Decrement the blocks remaining counter */
272 TotalBlocks--;
273 }
274
275 /* If the endpoint is full, send its contents to the host */
276 if (!(Endpoint_IsReadWriteAllowed()))
277 Endpoint_ClearIN();
278
279 /* Deselect all Dataflash chips */
280 Dataflash_DeselectChip();
281 }
282
283 /** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board Dataflash IC(s), from
284 * the given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the
285 * Dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the
286 * Dataflash.
287 *
288 * \param[in] BlockAddress Data block starting address for the write sequence
289 * \param[in] TotalBlocks Number of blocks of data to write
290 * \param[in] BufferPtr Pointer to the data source RAM buffer
291 */
292 void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress,
293 uint16_t TotalBlocks,
294 uint8_t* BufferPtr)
295 {
296 uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
297 uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
298 uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
299 bool UsingSecondBuffer = false;
300
301 /* Select the correct starting Dataflash IC for the block requested */
302 Dataflash_SelectChipFromPage(CurrDFPage);
303
304 #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
305 /* Copy selected dataflash's current page contents to the Dataflash buffer */
306 Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
307 Dataflash_SendAddressBytes(CurrDFPage, 0);
308 Dataflash_WaitWhileBusy();
309 #endif
310
311 /* Send the Dataflash buffer write command */
312 Dataflash_SendByte(DF_CMD_BUFF1WRITE);
313 Dataflash_SendAddressBytes(0, CurrDFPageByte);
314
315 while (TotalBlocks)
316 {
317 uint8_t BytesInBlockDiv16 = 0;
318
319 /* Write an endpoint packet sized data block to the Dataflash */
320 while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
321 {
322 /* Check if end of Dataflash page reached */
323 if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
324 {
325 /* Write the Dataflash buffer contents back to the Dataflash page */
326 Dataflash_WaitWhileBusy();
327 Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
328 Dataflash_SendAddressBytes(CurrDFPage, 0);
329
330 /* Reset the Dataflash buffer counter, increment the page counter */
331 CurrDFPageByteDiv16 = 0;
332 CurrDFPage++;
333
334 /* Once all the Dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */
335 if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS))
336 UsingSecondBuffer = !(UsingSecondBuffer);
337
338 /* Select the next Dataflash chip based on the new Dataflash page index */
339 Dataflash_SelectChipFromPage(CurrDFPage);
340
341 #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
342 /* If less than one Dataflash page remaining, copy over the existing page to preserve trailing data */
343 if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
344 {
345 /* Copy selected dataflash's current page contents to the Dataflash buffer */
346 Dataflash_WaitWhileBusy();
347 Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
348 Dataflash_SendAddressBytes(CurrDFPage, 0);
349 Dataflash_WaitWhileBusy();
350 }
351 #endif
352
353 /* Send the Dataflash buffer write command */
354 Dataflash_ToggleSelectedChipCS();
355 Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
356 Dataflash_SendAddressBytes(0, 0);
357 }
358
359 /* Write one 16-byte chunk of data to the Dataflash */
360 for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
361 Dataflash_SendByte(*(BufferPtr++));
362
363 /* Increment the Dataflash page 16 byte block counter */
364 CurrDFPageByteDiv16++;
365
366 /* Increment the block 16 byte block counter */
367 BytesInBlockDiv16++;
368 }
369
370 /* Decrement the blocks remaining counter */
371 TotalBlocks--;
372 }
373
374 /* Write the Dataflash buffer contents back to the Dataflash page */
375 Dataflash_WaitWhileBusy();
376 Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
377 Dataflash_SendAddressBytes(CurrDFPage, 0x00);
378 Dataflash_WaitWhileBusy();
379
380 /* Deselect all Dataflash chips */
381 Dataflash_DeselectChip();
382 }
383
384 /** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board Dataflash IC(s), into
385 * the preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash
386 * and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read
387 * the files stored on the Dataflash.
388 *
389 * \param[in] BlockAddress Data block starting address for the read sequence
390 * \param[in] TotalBlocks Number of blocks of data to read
391 * \param[out] BufferPtr Pointer to the data destination RAM buffer
392 */
393 void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress,
394 uint16_t TotalBlocks,
395 uint8_t* BufferPtr)
396 {
397 uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
398 uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
399 uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
400
401 /* Select the correct starting Dataflash IC for the block requested */
402 Dataflash_SelectChipFromPage(CurrDFPage);
403
404 /* Send the Dataflash main memory page read command */
405 Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
406 Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);
407 Dataflash_SendByte(0x00);
408 Dataflash_SendByte(0x00);
409 Dataflash_SendByte(0x00);
410 Dataflash_SendByte(0x00);
411
412 while (TotalBlocks)
413 {
414 uint8_t BytesInBlockDiv16 = 0;
415
416 /* Write an endpoint packet sized data block to the Dataflash */
417 while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))
418 {
419 /* Check if end of Dataflash page reached */
420 if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
421 {
422 /* Reset the Dataflash buffer counter, increment the page counter */
423 CurrDFPageByteDiv16 = 0;
424 CurrDFPage++;
425
426 /* Select the next Dataflash chip based on the new Dataflash page index */
427 Dataflash_SelectChipFromPage(CurrDFPage);
428
429 /* Send the Dataflash main memory page read command */
430 Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);
431 Dataflash_SendAddressBytes(CurrDFPage, 0);
432 Dataflash_SendByte(0x00);
433 Dataflash_SendByte(0x00);
434 Dataflash_SendByte(0x00);
435 Dataflash_SendByte(0x00);
436 }
437
438 /* Read one 16-byte chunk of data from the Dataflash */
439 for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)
440 *(BufferPtr++) = Dataflash_ReceiveByte();
441
442 /* Increment the Dataflash page 16 byte block counter */
443 CurrDFPageByteDiv16++;
444
445 /* Increment the block 16 byte block counter */
446 BytesInBlockDiv16++;
447 }
448
449 /* Decrement the blocks remaining counter */
450 TotalBlocks--;
451 }
452
453 /* Deselect all Dataflash chips */
454 Dataflash_DeselectChip();
455 }
456
457 /** Disables the Dataflash memory write protection bits on the board Dataflash ICs, if enabled. */
458 void DataflashManager_ResetDataflashProtections(void)
459 {
460 /* Select first Dataflash chip, send the read status register command */
461 Dataflash_SelectChip(DATAFLASH_CHIP1);
462 Dataflash_SendByte(DF_CMD_GETSTATUS);
463
464 /* Check if sector protection is enabled */
465 if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
466 {
467 Dataflash_ToggleSelectedChipCS();
468
469 /* Send the commands to disable sector protection */
470 Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
471 Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
472 Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
473 Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
474 }
475
476 /* Select second Dataflash chip (if present on selected board), send read status register command */
477 #if (DATAFLASH_TOTALCHIPS == 2)
478 Dataflash_SelectChip(DATAFLASH_CHIP2);
479 Dataflash_SendByte(DF_CMD_GETSTATUS);
480
481 /* Check if sector protection is enabled */
482 if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)
483 {
484 Dataflash_ToggleSelectedChipCS();
485
486 /* Send the commands to disable sector protection */
487 Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);
488 Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);
489 Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);
490 Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);
491 }
492 #endif
493
494 /* Deselect current Dataflash chip */
495 Dataflash_DeselectChip();
496 }
497
498 /** Performs a simple test on the attached Dataflash IC(s) to ensure that they are working.
499 *
500 * \return Boolean \c true if all media chips are working, \c false otherwise
501 */
502 bool DataflashManager_CheckDataflashOperation(void)
503 {
504 uint8_t ReturnByte;
505
506 /* Test first Dataflash IC is present and responding to commands */
507 Dataflash_SelectChip(DATAFLASH_CHIP1);
508 Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
509 ReturnByte = Dataflash_ReceiveByte();
510 Dataflash_DeselectChip();
511
512 /* If returned data is invalid, fail the command */
513 if (ReturnByte != DF_MANUFACTURER_ATMEL)
514 return false;
515
516 #if (DATAFLASH_TOTALCHIPS == 2)
517 /* Test second Dataflash IC is present and responding to commands */
518 Dataflash_SelectChip(DATAFLASH_CHIP2);
519 Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);
520 ReturnByte = Dataflash_ReceiveByte();
521 Dataflash_DeselectChip();
522
523 /* If returned data is invalid, fail the command */
524 if (ReturnByte != DF_MANUFACTURER_ATMEL)
525 return false;
526 #endif
527
528 return true;
529 }
530
Imprint / Impressum