mmc.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /*#######################################################################################
  2. Connect AVR to MMC/SD
  3. Copyright (C) 2004 Ulrich Radig
  4. Bei Fragen und Verbesserungen wendet euch per EMail an
  5. mail@ulrichradig.de
  6. oder im Forum meiner Web Page : www.ulrichradig.de
  7. Dieses Programm ist freie Software. Sie können es unter den Bedingungen der
  8. GNU General Public License, wie von der Free Software Foundation veröffentlicht,
  9. weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder
  10. (nach Ihrer Option) jeder späteren Version.
  11. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung,
  12. daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
  13. sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
  14. FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.
  15. Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
  16. Programm erhalten haben.
  17. Falls nicht, schreiben Sie an die Free Software Foundation,
  18. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  19. #######################################################################################*/
  20. #include "mmc.h"
  21. #include <util/delay.h>
  22. //############################################################################
  23. //Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
  24. unsigned char mmc_init ()
  25. //############################################################################
  26. {
  27. unsigned int Timeout = 0,i;
  28. //Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde
  29. DDRC |= ( (1<<MMC_DO) | (1<<MMC_CS) | (1<<MMC_CLK) );
  30. DDRC &= ~(1<<MMC_DI);
  31. PORTC |= ( (1<<MMC_DO) | (1<<MMC_DI) | (1<<MMC_CS) );
  32. //Wartet eine kurze Zeit
  33. _delay_ms(10);
  34. //Initialisiere MMC/SD-Karte in den SPI-Mode
  35. for(i=0; i<250; i++)
  36. {
  37. PORTC ^= (1<<MMC_CLK);
  38. _delay_us(4);
  39. }
  40. PORTC &= ~(1<<MMC_CLK);
  41. _delay_us(10);
  42. PORTC &= ~(1<<MMC_CS);
  43. _delay_us(3);
  44. //Sendet Commando CMD0 an MMC/SD-Karte
  45. unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
  46. while(mmc_write_command (CMD) !=1)
  47. {
  48. if (Timeout++ > 20)
  49. {
  50. MMC_Disable();
  51. return(1); //Abbruch bei Commando1 (Return Code1)
  52. }
  53. }
  54. //Sendet Commando CMD1 an MMC/SD-Karte
  55. Timeout = 0;
  56. CMD[0] = 0x41;//Commando 1
  57. CMD[5] = 0xFF;
  58. while( mmc_write_command (CMD) !=0)
  59. {
  60. if (Timeout++ > 800)
  61. {
  62. MMC_Disable();
  63. return(9); //Abbruch bei Commando2 (Return Code2)
  64. }
  65. }
  66. return(0);
  67. }
  68. //############################################################################
  69. //Sendet ein Commando an die MMC/SD-Karte
  70. unsigned char mmc_write_command (unsigned char *cmd)
  71. //############################################################################
  72. {
  73. unsigned char tmp = 0xff;
  74. unsigned int Timeout = 0;
  75. //sendet 6 Byte Commando
  76. for (unsigned char a = 0;a<0x06;a++) //sendet 6 Byte Commando zur MMC/SD-Karte
  77. {
  78. mmc_write_byte(*cmd++);
  79. }
  80. //Wartet auf ein gültige Antwort von der MMC/SD-Karte
  81. while (tmp == 0xff)
  82. {
  83. tmp = mmc_read_byte();
  84. if (Timeout++ > 50)
  85. {
  86. break; //Abbruch da die MMC/SD-Karte nicht Antwortet
  87. }
  88. }
  89. return(tmp);
  90. }
  91. //############################################################################
  92. //Routine zum Empfangen eines Bytes von der MMC-Karte
  93. unsigned char mmc_read_byte (void)
  94. //############################################################################
  95. {
  96. uint8_t Byte=0,j;
  97. for(j=0; j<8; j++){
  98. Byte = (Byte<<1);
  99. PORTC |= (1<<MMC_CLK);
  100. _delay_us(4);
  101. if(PINC & (1<<MMC_DI)){
  102. Byte |= 1;
  103. }
  104. else{
  105. Byte &= ~1;
  106. }
  107. PORTC &= ~(1<<MMC_CLK);
  108. _delay_us(4);
  109. }
  110. return (Byte);
  111. }
  112. //############################################################################
  113. //Routine zum Senden eines Bytes zur MMC-Karte
  114. void mmc_write_byte (unsigned char Byte)
  115. //############################################################################
  116. {
  117. uint8_t i;
  118. for(i=0; i<8; i++){
  119. if(Byte & 0x80){
  120. PORTC |= (1<<MMC_DO);
  121. }
  122. else{
  123. PORTC &= ~(1<<MMC_DO);
  124. }
  125. Byte = (Byte<<1);
  126. PORTC |= (1<<MMC_CLK);
  127. _delay_us(4);
  128. PORTC &= ~(1<<MMC_CLK);
  129. _delay_us(4);
  130. }
  131. PORTC |= (1<<MMC_DO);
  132. }
  133. //############################################################################
  134. //Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte
  135. unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
  136. //############################################################################
  137. {
  138. unsigned char tmp;
  139. //Commando 24 zum schreiben eines Blocks auf die MMC/SD - Karte
  140. unsigned char cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
  141. /*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
  142. addr wird von Blocks zu Bytes umgerechnet danach werden
  143. diese in das Commando eingefügt*/
  144. addr = addr << 9; //addr = addr * 512
  145. cmd[1] = ((addr & 0xFF000000) >>24 );
  146. cmd[2] = ((addr & 0x00FF0000) >>16 );
  147. cmd[3] = ((addr & 0x0000FF00) >>8 );
  148. //Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes)
  149. tmp = mmc_write_command (cmd);
  150. if (tmp != 0)
  151. {
  152. return(tmp);
  153. }
  154. //Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte
  155. for (unsigned char a=0;a<100;a++)
  156. {
  157. mmc_read_byte();
  158. }
  159. //Sendet Start Byte an MMC/SD-Karte
  160. mmc_write_byte(0xFE);
  161. //Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte
  162. for (unsigned int a=0;a<512;a++)
  163. {
  164. mmc_write_byte(*Buffer++);
  165. }
  166. //CRC-Byte schreiben
  167. mmc_write_byte(0xFF); //Schreibt Dummy CRC
  168. mmc_write_byte(0xFF); //CRC Code wird nicht benutzt
  169. //Fehler beim schreiben? (Data Response XXX00101 = OK)
  170. if((mmc_read_byte()&0x1F) != 0x05) return(1);
  171. //Wartet auf MMC/SD-Karte Bussy
  172. while (mmc_read_byte() != 0xff){};
  173. return(0);
  174. }
  175. //############################################################################
  176. //Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
  177. void mmc_read_block(unsigned char *cmd,unsigned char *Buffer,unsigned int Bytes)
  178. //############################################################################
  179. {
  180. //Sendet Commando cmd an MMC/SD-Karte
  181. if (mmc_write_command (cmd) != 0)
  182. {
  183. return;
  184. }
  185. //Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte)
  186. while (mmc_read_byte() != 0xfe){};
  187. //Lesen des Bolcks (normal 512Bytes) von MMC/SD-Karte
  188. for (unsigned int a=0;a<Bytes;a++)
  189. {
  190. *Buffer++ = mmc_read_byte();
  191. }
  192. //CRC-Byte auslesen
  193. mmc_read_byte();//CRC - Byte wird nicht ausgewertet
  194. mmc_read_byte();//CRC - Byte wird nicht ausgewertet
  195. return;
  196. }
  197. //############################################################################
  198. //Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte
  199. unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer)
  200. //############################################################################
  201. {
  202. //Commando 16 zum lesen eines Blocks von der MMC/SD - Karte
  203. unsigned char cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
  204. /*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
  205. addr wird von Blocks zu Bytes umgerechnet danach werden
  206. diese in das Commando eingefügt*/
  207. addr = addr << 9; //addr = addr * 512
  208. cmd[1] = ((addr & 0xFF000000) >>24 );
  209. cmd[2] = ((addr & 0x00FF0000) >>16 );
  210. cmd[3] = ((addr & 0x0000FF00) >>8 );
  211. mmc_read_block(cmd,Buffer,512);
  212. return(0);
  213. }
  214. //############################################################################
  215. //Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
  216. unsigned char mmc_read_cid (unsigned char *Buffer)
  217. //############################################################################
  218. {
  219. //Commando zum lesen des CID Registers
  220. unsigned char cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
  221. mmc_read_block(cmd,Buffer,16);
  222. return(0);
  223. }
  224. //############################################################################
  225. //Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes)
  226. unsigned char mmc_read_csd (unsigned char *Buffer)
  227. //############################################################################
  228. {
  229. //Commando zum lesen des CSD Registers
  230. unsigned char cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
  231. mmc_read_block(cmd,Buffer,16);
  232. return(0);
  233. }