1 | unsigned char MMC_FLASH_Write (unsigned long address, unsigned char *scratch,
|
2 | unsigned char *wdata, unsigned int length)
|
3 | {
|
4 | idata unsigned long flash_page_1; // First FLASH page address;
|
5 | idata unsigned long flash_page_2; // Second FLASH page address;
|
6 | idata unsigned int card_status; // Stores status returned from MMC;
|
7 | idata unsigned int counter; // Byte counter used for writes to
|
8 | // local copy of data block;
|
9 | unsigned char xdata *index; // Pointer into local copy of data
|
10 | // block, used during modification;
|
11 | MMC_FLASH_Clear(address,scratch,length); // Clear desired write space;
|
12 | if(length > 512) return 0; // Check for valid data length;
|
13 | // Calculate first FLASH page address;
|
14 | flash_page_1 = address & ~(PHYSICAL_BLOCK_SIZE-1);
|
15 | // Calculate second FLASH page address;
|
16 | flash_page_2 = (address+length-1) & ~(PHYSICAL_BLOCK_SIZE-1);
|
17 | if(flash_page_1 == flash_page_2) // Handle single FLASH block condition;
|
18 | {
|
19 | // Set block length to default block
|
20 | // size (512 bytes);
|
21 | card_status = MMC_Command_Exec(SET_BLOCKLEN,
|
22 | (unsigned long)PHYSICAL_BLOCK_SIZE,
|
23 | EMPTY);
|
24 | // Read data block;
|
25 | card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
|
26 | index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE + scratch);
|
27 | counter = 0;
|
28 | while(counter<length) // Modify write space in local copy;
|
29 | {
|
30 | *index++ = *wdata++;
|
31 | counter++;
|
32 | }
|
33 | // Write modified block back to MMC;
|
34 | card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
|
35 | }
|
36 | else // Handle multiple FLASH block
|
37 | { // condition;
|
38 | // Set block length to default block
|
39 | // size (512 bytes);
|
40 | card_status = MMC_Command_Exec(SET_BLOCKLEN,
|
41 | (unsigned long)PHYSICAL_BLOCK_SIZE,
|
42 | EMPTY);
|
43 | // Read first data block;
|
44 | card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_1,scratch);
|
45 | index = (unsigned int)(address % PHYSICAL_BLOCK_SIZE + scratch);
|
46 | counter = (unsigned int)(flash_page_2 - address);
|
47 | while(counter > 0) // Modify data in local copy of first
|
48 | { // block;
|
49 | *index++ = *wdata++;
|
50 | counter--;
|
51 | }
|
52 | // Write local copy back to MMC;
|
53 | card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_1,scratch);
|
54 | // Read second data block;
|
55 | card_status = MMC_Command_Exec(READ_SINGLE_BLOCK,flash_page_2,scratch);
|
56 | @@@ index = scratch;
|
57 | counter = (unsigned int)(length - (flash_page_2 - address));
|
58 | while(counter > 0) // Modify data in local copy of second
|
59 | { // block;
|
60 | *index++ = *wdata++;
|
61 | counter--;
|
62 | }
|
63 | // Write local copy back to MMC;
|
64 | card_status = MMC_Command_Exec(WRITE_BLOCK,flash_page_2,scratch);
|
65 | }
|
66 | }
|