?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik /*! \file mmc.c \brief MultiMedia and SD Flash Card Interface. */
2 //*****************************************************************************
3 //
4 // File Name : 'mmc.c'
5 // Title : MultiMedia and SD Flash Card Interface
6 // Author : Pascal Stang - Copyright (C) 2004
7 // Created : 2004.09.22
8 // Revised : 2006.06.12
9 // Version : 0.1
10 // Target MCU : Atmel AVR Series
11 // Editor Tabs : 4
12 //
13 // NOTE: This code is currently below version 1.0, and therefore is considered
14 // to be lacking in some functionality or documentation, or may not be fully
15 // tested. Nonetheless, you can expect most functions to work.
16 //
17 // This code is distributed under the GNU Public License
18 // which can be found at http://www.gnu.org/licenses/gpl.txt
19 //
20 //*****************************************************************************
21  
22 //----- Include Files ---------------------------------------------------------
23 #include <avr/io.h> // include I/O definitions (port names, pin names, etc)
24 #include <avr/interrupt.h> // include interrupt support
25  
26 #include "global.h" // include our global settings
27 #include "spi.h" // include spi bus support
28  
29 #include "rprintf.h"
30  
31 #include "mmc.h"
32  
33 // include project-specific hardware configuration
34 #include "mmcconf.h"
35  
36 // Global variables
37  
38 // Functions
39  
40 void mmcInit(void)
41 {
42 // initialize SPI interface
43 spiInit();
44 // release chip select
45 sbi(MMC_CS_DDR, MMC_CS_PIN);
46 sbi(MMC_CS_PORT,MMC_CS_PIN);
47 }
48  
49 u08 mmcReset(void)
50 {
51 u08 i;
52 u08 retry;
53 u08 r1=0;
54  
55 retry = 0;
56 do
57 {
58 // send dummy bytes with CS high before accessing
59 for(i=0;i<10;i++) spiTransferByte(0xFF);
60 // resetting card, go to SPI mode
61 r1 = mmcSendCommand(MMC_GO_IDLE_STATE, 0);
62 #ifdef MMC_DEBUG
63 rprintf("MMC_GO_IDLE_STATE: R1=0x%x\r\n", r1);
64 #endif
65 // do retry counter
66 retry++;
67 if(retry>10) return -1;
68 } while(r1 != 0x01);
69  
70 // TODO: check card parameters for voltage compliance
71 // before issuing initialize command
72  
73 retry = 0;
74 do
75 {
76 // initializing card for operation
77 r1 = mmcSendCommand(MMC_SEND_OP_COND, 0);
78 #ifdef MMC_DEBUG
79 rprintf("MMC_SEND_OP_COND: R1=0x%x\r\n", r1);
80 #endif
81 // do retry counter
82 retry++;
83 if(retry>100) return -1;
84 } while(r1);
85  
86 // turn off CRC checking to simplify communication
87 r1 = mmcSendCommand(MMC_CRC_ON_OFF, 0);
88 #ifdef MMC_DEBUG
89 rprintf("MMC_CRC_ON_OFF: R1=0x%x\r\n", r1);
90 #endif
91  
92 // set block length to 512 bytes
93 r1 = mmcSendCommand(MMC_SET_BLOCKLEN, 512);
94 #ifdef MMC_DEBUG
95 rprintf("MMC_SET_BLOCKLEN: R1=0x%x\r\n", r1);
96 #endif
97  
98 // return success
99 return 0;
100 }
101  
102 u08 mmcSendCommand(u08 cmd, u32 arg)
103 {
104 u08 r1;
105  
106 // assert chip select
107 cbi(MMC_CS_PORT,MMC_CS_PIN);
108 // issue the command
109 r1 = mmcCommand(cmd, arg);
110 // release chip select
111 sbi(MMC_CS_PORT,MMC_CS_PIN);
112  
113 return r1;
114 }
115  
116 u08 mmcRead(u32 sector, u08* buffer)
117 {
118 u08 r1;
119 u16 i;
120  
121 // assert chip select
122 cbi(MMC_CS_PORT,MMC_CS_PIN);
123 // issue command
124 r1 = mmcCommand(MMC_READ_SINGLE_BLOCK, sector<<9);
125 #ifdef MMC_DEBUG
126 rprintf("MMC Read Block R1=0x%x\r\n", r1);
127 #endif
128 // check for valid response
129 if(r1 != 0x00)
130 return r1;
131 // wait for block start
132 while(spiTransferByte(0xFF) != MMC_STARTBLOCK_READ);
133 // read in data
134 for(i=0; i<0x200; i++)
135 {
136 *buffer++ = spiTransferByte(0xFF);
137 }
138 // read 16-bit CRC
139 spiTransferByte(0xFF);
140 spiTransferByte(0xFF);
141 // release chip select
142 sbi(MMC_CS_PORT,MMC_CS_PIN);
143 // return success
144 return 0;
145 }
146  
147 u08 mmcWrite(u32 sector, u08* buffer)
148 {
149 u08 r1;
150 u16 i;
151  
152 // assert chip select
153 cbi(MMC_CS_PORT,MMC_CS_PIN);
154 // issue command
155 r1 = mmcCommand(MMC_WRITE_BLOCK, sector<<9);
156 #ifdef MMC_DEBUG
157 rprintf("MMC Write Block R1=0x%x\r\n", r1);
158 #endif
159 // check for valid response
160 if(r1 != 0x00)
161 return r1;
162 // send dummy
163 spiTransferByte(0xFF);
164 // send data start token
165 spiTransferByte(MMC_STARTBLOCK_WRITE);
166 // write data
167 for(i=0; i<0x200; i++)
168 {
169 spiTransferByte(*buffer++);
170 }
171 // write 16-bit CRC (dummy values)
172 spiTransferByte(0xFF);
173 spiTransferByte(0xFF);
174 // read data response token
175 r1 = spiTransferByte(0xFF);
176 if( (r1&MMC_DR_MASK) != MMC_DR_ACCEPT)
177 return r1;
178 #ifdef MMC_DEBUG
179 rprintf("Data Response Token=0x%x\r\n", r1);
180 #endif
181 // wait until card not busy
182 while(!spiTransferByte(0xFF));
183 // release chip select
184 sbi(MMC_CS_PORT,MMC_CS_PIN);
185 // return success
186 return 0;
187 }
188  
189 u08 mmcCommand(u08 cmd, u32 arg)
190 {
191 u08 r1;
192 u08 retry=0;
193 // send command
194 spiTransferByte(cmd | 0x40);
195 spiTransferByte(arg>>24);
196 spiTransferByte(arg>>16);
197 spiTransferByte(arg>>8);
198 spiTransferByte(arg);
199 spiTransferByte(0x95); // crc valid only for MMC_GO_IDLE_STATE
200 // end command
201 // wait for response
202 // if more than 8 retries, card has timed-out
203 // return the received 0xFF
204 while((r1 = spiTransferByte(0xFF)) == 0xFF)
205 if(retry++ > 8) break;
206 // return response
207 return r1;
208 }
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3