1 | unsigned char MMC_FLASH_Clear (unsigned long address, unsigned char *scratch,
|
2 | unsigned int length)
|
3 | {
|
4 | idata unsigned long flash_page_1; // Stores address of first FLASH page;
|
5 | idata unsigned long flash_page_2; // Stores address of second FLASH page;
|
6 | idata unsigned int card_status; // Stores MMC status after each MMC
|
7 | // command;
|
8 | idata unsigned int counter; // Counter for clearing bytes in local
|
9 | // block copy;
|
10 | unsigned char xdata *index; // Index into local block used for
|
11 | // clearing desired data;
|
12 | if(length > 512) return 0; // Test desired clear length; If
|
13 | // length > 512, break out and return
|
14 | // zero;
|
15 | // Calculate first FLASH page address;
|
16 | flash_page_1 = address & ~(PHYSICAL_BLOCK_SIZE-1);
|
17 | // Calculate second FLASH page address;
|
18 | flash_page_2 = (address+length-1) & ~(PHYSICAL_BLOCK_SIZE-1);
|
19 | if(flash_page_1 == flash_page_2) // Clear space all in one FLASH block
|
20 | { // condition;
|
21 | // Read first FLASH block;
|
22 | card_status = MMC_Command_Exec(SET_BLOCKLEN,
|
23 | (unsigned long)PHYSICAL_BLOCK_SIZE,
|
24 | EMPTY);
|
25 | card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
|
26 | // Set index to address of area to clear
|
27 | // in local block;
|
28 | @@ index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
|
29 | counter = 0;
|
30 | while(counter<length) // Clear desired area in local block;
|
31 | {
|
32 | *index++ = 0x00;
|
33 | counter++;
|
34 | }
|
35 | // Tag first FLASH page for erase;
|
36 | card_status = MMC_Command_Exec(TAG_SECTOR_START,flash_page_1,EMPTY);
|
37 | card_status = MMC_Command_Exec(TAG_SECTOR_END,flash_page_1,EMPTY);
|
38 | // Erase first FLASH page;
|
39 | card_status = MMC_Command_Exec(ERASE,EMPTY,EMPTY);
|
40 | // Write local copy of block back out
|
41 | // to MMC;
|
42 | card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
|
43 | }
|
44 | else // Clear space crosses FLASH block
|
45 | { // boundaries condition;
|
46 | // Follow same procedure as for single
|
47 | // block case above; Read first block
|
48 | // clear data from start address to end
|
49 | // of block; Erase block in FLASH;
|
50 | // Write local copy back out;
|
51 | card_status = MMC_Command_Exec(SET_BLOCKLEN,
|
52 | (unsigned long)PHYSICAL_BLOCK_SIZE,
|
53 | EMPTY);
|
54 | card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
|
55 | @@ index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE) + scratch;
|
56 | counter = (unsigned int)(flash_page_2 - address);
|
57 | while(counter > 0)
|
58 | {
|
59 | *index++ = 0xFF;
|
60 | counter--;
|
61 | }
|
62 | card_status = MMC_Command_Exec(TAG_SECTOR_END,flash_page_1,EMPTY);
|
63 | card_status = MMC_Command_Exec(ERASE,EMPTY,EMPTY);
|
64 | card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
|
65 | // Same process as above, but using
|
66 | // second FLASH block; Area to be
|
67 | // cleared extends from beginning of
|
68 | // second FLASH block to end of desired
|
69 | // clear area;
|
70 | card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_2,scratch);
|
71 | @@ index = scratch;
|
72 | counter = (unsigned int)(length - (flash_page_2 - address));
|
73 | while(counter > 0)
|
74 | {
|
75 | *index++ = 0xFF;
|
76 | counter--;
|
77 | }
|
78 | card_status = MMC_Command_Exec(TAG_SECTOR_END,flash_page_2,EMPTY);
|
79 | card_status = MMC_Command_Exec(ERASE,EMPTY,EMPTY);
|
80 | card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_2,scratch);
|
81 | }
|
82 | }
|