mmc.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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. //############################################################################
  22. //Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE)
  23. unsigned char mmc_init ()
  24. //############################################################################
  25. {
  26. unsigned int Timeout = 0;
  27. //Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde
  28. MMC_Direction_REG &=~(1<<SPI_DI); //Setzen von Pin MMC_DI auf Input
  29. MMC_Direction_REG |= (1<<SPI_Clock); //Setzen von Pin MMC_Clock auf Output
  30. MMC_Direction_REG |= (1<<SPI_DO); //Setzen von Pin MMC_DO auf Output
  31. MMC_Direction_REG |= (1<<MMC_Chip_Select); //Setzen von Pin MMC_Chip_Select auf Output
  32. MMC_Direction_REG |= (1<<SPI_SS);
  33. MMC_Write |= (1<<MMC_Chip_Select); //Setzt den Pin MMC_Chip_Select auf High Pegel
  34. for(unsigned char a=0;a<200;a++){
  35. nop();
  36. }; //Wartet eine kurze Zeit
  37. #if SPI_Mode
  38. //Aktiviren des SPI - Bus, Clock = Idel LOW
  39. //SPI Clock teilen durch 128
  40. SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); //Enable SPI, SPI in Master Mode
  41. SPSR = (0<<SPI2X);
  42. #endif
  43. //Initialisiere MMC/SD-Karte in den SPI-Mode
  44. for (unsigned char b = 0;b<0x0f;b++) //Sendet min 74+ Clocks an die MMC/SD-Karte
  45. {
  46. mmc_write_byte(0xff);
  47. }
  48. //Sendet Commando CMD0 an MMC/SD-Karte
  49. unsigned char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
  50. while(mmc_write_command (CMD) !=1)
  51. {
  52. if (Timeout++ > 200)
  53. {
  54. MMC_Disable();
  55. return(1); //Abbruch bei Commando1 (Return Code1)
  56. }
  57. }
  58. //Sendet Commando CMD1 an MMC/SD-Karte
  59. Timeout = 0;
  60. CMD[0] = 0x41;//Commando 1
  61. CMD[5] = 0xFF;
  62. while( mmc_write_command (CMD) !=0)
  63. {
  64. if (Timeout++ > 400)
  65. {
  66. MMC_Disable();
  67. return(2); //Abbruch bei Commando2 (Return Code2)
  68. }
  69. }
  70. #if SPI_Mode
  71. //SPI Bus auf max Geschwindigkeit
  72. SPCR &= ~((1<<SPR0) | (1<<SPR1));
  73. SPSR = SPSR|(1<<SPI2X);
  74. #endif
  75. //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
  76. MMC_Disable();
  77. return(0);
  78. }
  79. //############################################################################
  80. //Sendet ein Commando an die MMC/SD-Karte
  81. unsigned char mmc_write_command (unsigned char *cmd)
  82. //############################################################################
  83. {
  84. unsigned char tmp = 0xff;
  85. unsigned int Timeout = 0;
  86. //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
  87. MMC_Disable();
  88. //sendet 8 Clock Impulse
  89. mmc_write_byte(0xFF);
  90. //set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
  91. MMC_Enable();
  92. //sendet 6 Byte Commando
  93. for (unsigned char a = 0;a<0x06;a++) //sendet 6 Byte Commando zur MMC/SD-Karte
  94. {
  95. mmc_write_byte(*cmd++);
  96. }
  97. //Wartet auf ein gültige Antwort von der MMC/SD-Karte
  98. while (tmp == 0xff)
  99. {
  100. tmp = mmc_read_byte();
  101. if (Timeout++ > 500)
  102. {
  103. break; //Abbruch da die MMC/SD-Karte nicht Antwortet
  104. }
  105. }
  106. return(tmp);
  107. }
  108. //############################################################################
  109. //Routine zum Empfangen eines Bytes von der MMC-Karte
  110. unsigned char mmc_read_byte (void)
  111. //############################################################################
  112. {
  113. unsigned char Byte = 0;
  114. #if SPI_Mode //Routine für Hardware SPI
  115. SPDR = 0xff;
  116. while(!(SPSR & (1<<SPIF))){};
  117. Byte = SPDR;
  118. #else //Routine für Software SPI
  119. for (unsigned char a=8; a>0; a--) //das Byte wird Bitweise nacheinander Empangen MSB First
  120. {
  121. MMC_Write &=~(1<<SPI_Clock); //erzeugt ein Clock Impuls (Low)
  122. if (bit_is_set(MMC_Read,SPI_DI) > 0) //Lesen des Pegels von MMC_DI
  123. {
  124. Byte |= (1<<(a-1));
  125. }
  126. else
  127. {
  128. Byte &=~(1<<(a-1));
  129. }
  130. MMC_Write |=(1<<SPI_Clock); //setzt Clock Impuls wieder auf (High)
  131. }
  132. #endif
  133. return (Byte);
  134. }
  135. //############################################################################
  136. //Routine zum Senden eines Bytes zur MMC-Karte
  137. void mmc_write_byte (unsigned char Byte)
  138. //############################################################################
  139. {
  140. #if SPI_Mode //Routine für Hardware SPI
  141. SPDR = Byte; //Sendet ein Byte
  142. while(!(SPSR & (1<<SPIF))) //Wartet bis Byte gesendet wurde
  143. {
  144. }
  145. #else //Routine für Software SPI
  146. for (unsigned char a=8; a>0; a--) //das Byte wird Bitweise nacheinander Gesendet MSB First
  147. {
  148. if (bit_is_set(Byte,(a-1))>0) //Ist Bit a in Byte gesetzt
  149. {
  150. MMC_Write |= (1<<SPI_DO); //Set Output High
  151. }
  152. else
  153. {
  154. MMC_Write &= ~(1<<SPI_DO); //Set Output Low
  155. }
  156. MMC_Write &= ~(1<<SPI_Clock); //erzeugt ein Clock Impuls (LOW)
  157. MMC_Write |= (1<<SPI_Clock); //setzt Clock Impuls wieder auf (High)
  158. }
  159. MMC_Write |= (1<<SPI_DO); //setzt Output wieder auf High
  160. #endif
  161. }
  162. //############################################################################
  163. //Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte
  164. unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
  165. //############################################################################
  166. {
  167. unsigned char tmp;
  168. //Commando 24 zum schreiben eines Blocks auf die MMC/SD - Karte
  169. unsigned char cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
  170. /*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
  171. addr wird von Blocks zu Bytes umgerechnet danach werden
  172. diese in das Commando eingefügt*/
  173. addr = addr << 9; //addr = addr * 512
  174. cmd[1] = ((addr & 0xFF000000) >>24 );
  175. cmd[2] = ((addr & 0x00FF0000) >>16 );
  176. cmd[3] = ((addr & 0x0000FF00) >>8 );
  177. //Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes)
  178. tmp = mmc_write_command (cmd);
  179. if (tmp != 0)
  180. {
  181. return(tmp);
  182. }
  183. //Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte
  184. for (unsigned char a=0;a<100;a++)
  185. {
  186. mmc_read_byte();
  187. }
  188. //Sendet Start Byte an MMC/SD-Karte
  189. mmc_write_byte(0xFE);
  190. //Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte
  191. for (unsigned int a=0;a<512;a++)
  192. {
  193. mmc_write_byte(*Buffer++);
  194. }
  195. //CRC-Byte schreiben
  196. mmc_write_byte(0xFF); //Schreibt Dummy CRC
  197. mmc_write_byte(0xFF); //CRC Code wird nicht benutzt
  198. //Fehler beim schreiben? (Data Response XXX00101 = OK)
  199. if((mmc_read_byte()&0x1F) != 0x05) return(1);
  200. //Wartet auf MMC/SD-Karte Bussy
  201. while (mmc_read_byte() != 0xff){};
  202. //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
  203. MMC_Disable();
  204. return(0);
  205. }
  206. //############################################################################
  207. //Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
  208. void mmc_read_block(unsigned char *cmd,unsigned char *Buffer,unsigned int Bytes)
  209. //############################################################################
  210. {
  211. //Sendet Commando cmd an MMC/SD-Karte
  212. if (mmc_write_command (cmd) != 0)
  213. {
  214. return;
  215. }
  216. //Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte)
  217. while (mmc_read_byte() != 0xfe){};
  218. //Lesen des Bolcks (normal 512Bytes) von MMC/SD-Karte
  219. for (unsigned int a=0;a<Bytes;a++)
  220. {
  221. *Buffer++ = mmc_read_byte();
  222. }
  223. //CRC-Byte auslesen
  224. mmc_read_byte();//CRC - Byte wird nicht ausgewertet
  225. mmc_read_byte();//CRC - Byte wird nicht ausgewertet
  226. //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
  227. MMC_Disable();
  228. return;
  229. }
  230. //############################################################################
  231. //Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte
  232. unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer)
  233. //############################################################################
  234. {
  235. //Commando 16 zum lesen eines Blocks von der MMC/SD - Karte
  236. unsigned char cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
  237. /*Die Adressierung der MMC/SD-Karte wird in Bytes angegeben,
  238. addr wird von Blocks zu Bytes umgerechnet danach werden
  239. diese in das Commando eingefügt*/
  240. addr = addr << 9; //addr = addr * 512
  241. cmd[1] = ((addr & 0xFF000000) >>24 );
  242. cmd[2] = ((addr & 0x00FF0000) >>16 );
  243. cmd[3] = ((addr & 0x0000FF00) >>8 );
  244. mmc_read_block(cmd,Buffer,512);
  245. return(0);
  246. }
  247. //############################################################################
  248. //Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes)
  249. unsigned char mmc_read_cid (unsigned char *Buffer)
  250. //############################################################################
  251. {
  252. //Commando zum lesen des CID Registers
  253. unsigned char cmd[] = {0x4A,0x00,0x00,0x00,0x00,0xFF};
  254. mmc_read_block(cmd,Buffer,16);
  255. return(0);
  256. }
  257. //############################################################################
  258. //Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes)
  259. unsigned char mmc_read_csd (unsigned char *Buffer)
  260. //############################################################################
  261. {
  262. //Commando zum lesen des CSD Registers
  263. unsigned char cmd[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
  264. mmc_read_block(cmd,Buffer,16);
  265. return(0);
  266. }