1 | uint8_t mmc_write_multiblock ( uint32_t addr, uint8_t *Buffer, uint8_t numblocks )
|
2 | {
|
3 | uint8_t resp;
|
4 | uint8_t cmd[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF };
|
5 | #ifdef SPI_CRC
|
6 | uint16_t crc;
|
7 | #endif
|
8 |
|
9 | MMC_Enable();
|
10 |
|
11 | #ifdef MMC_PRESET_MULTIBLOCKCOUNT
|
12 | // wait until Card is ready
|
13 | do {
|
14 | SPDR = 0xff;
|
15 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
16 | } while ( !SPDR );
|
17 |
|
18 | //CMD55
|
19 | cmd[0] = 0x40 + 55;
|
20 | mmc_write_command ( cmd, 1 );
|
21 |
|
22 | //CMD23
|
23 | cmd[0] = 0x40 + 23;
|
24 | cmd[4] = numblocks;
|
25 | mmc_write_command ( cmd, 1 );
|
26 |
|
27 | // wait until Card is ready
|
28 | do {
|
29 | SPDR = 0xff;
|
30 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
31 | } while ( !SPDR );
|
32 | #endif
|
33 |
|
34 | addr = addr << 9; //addr = addr * 512
|
35 |
|
36 | //CMD25
|
37 | cmd[0] = 0x40 + 25;
|
38 | cmd[1] = ( ( addr & 0xFF000000 ) >> 24 );
|
39 | cmd[2] = ( ( addr & 0x00FF0000 ) >> 16 );
|
40 | cmd[3] = ( ( addr & 0x0000FF00 ) >> 8 );
|
41 | cmd[4] = 0;
|
42 |
|
43 | resp = mmc_write_command ( cmd, 1 );
|
44 | if ( resp > 1 ) {
|
45 | return ( 1 );
|
46 | }
|
47 |
|
48 | for ( uint8_t n = numblocks; n > 0; n-- ) {
|
49 | #ifdef SPI_CRC
|
50 | crc = crc16 ( Buffer, 512 );
|
51 | #endif
|
52 | // wait until Card is ready
|
53 | do {
|
54 | SPDR = 0xff;
|
55 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
56 | } while ( !SPDR );
|
57 |
|
58 | // Send multi-block start-token
|
59 | SPDR = 0xFC;
|
60 |
|
61 | //actually transfer the data
|
62 | for ( uint16_t i = 512; i; i-- ) {
|
63 | uint8_t data = *Buffer;
|
64 | Buffer++;
|
65 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
66 | SPDR = data;
|
67 | }
|
68 |
|
69 | // send CRC
|
70 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
71 | #ifdef SPI_CRC
|
72 | SPDR = crc >> 8;
|
73 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
74 | SPDR = crc & 0xFF;
|
75 | #else
|
76 | SPDR = 0xff;
|
77 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
78 | SPDR = 0xff;
|
79 | #endif
|
80 |
|
81 | #ifdef MMC_PRESET_MULTIBLOCKCOUNT
|
82 | // Pad 8
|
83 | SPDR = 0xff;
|
84 | #endif
|
85 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
86 |
|
87 | // Get response
|
88 | SPDR = 0xff;
|
89 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
90 | resp = SPDR;
|
91 | if ( ( resp & 0x0E ) != 4 )
|
92 | return ( 2 );
|
93 | }
|
94 |
|
95 | // wait until Card is ready
|
96 | do {
|
97 | SPDR = 0xff;
|
98 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
99 | } while ( !SPDR );
|
100 |
|
101 | // Send "transfer stop byte"
|
102 | SPDR = 0xFD;
|
103 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
104 |
|
105 | // Pad 8
|
106 | SPDR = 0xff;
|
107 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
108 |
|
109 | // wait until Card is ready
|
110 | do {
|
111 | SPDR = 0xff;
|
112 | while ( ! ( SPSR & ( 1 << SPIF ) ) );
|
113 | } while ( !SPDR );
|
114 |
|
115 | MMC_Disable();
|
116 |
|
117 | return ( 0 );
|
118 | }
|