Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.46 KB | None | 0 0
  1. /*
  2. SPI_Hardware.c
  3.  
  4. 10/14/2019
  5. Ron Mikulecky
  6. Elijah Whitmire
  7. */
  8. #include "Main.h"
  9. #include "SPI.h"
  10. #include "SPI_Hardware.h"
  11. #include <stdio.h>
  12.  
  13.  
  14. /***********************************************************************
  15. DESC: Sends SD card command over SPI
  16. INPUT: Command number, 32bit argument
  17. RETURNS: SD or SPI Error flags
  18. CAUTION: None
  19. ************************************************************************/
  20. uint8_t SD_send_command (uint8_t command, uint32_t argument)
  21. {
  22. uint8_t send_value, recv_value, return_value;
  23. uint8_t index;
  24.  
  25. if(command>=64)//Command out of range
  26. {
  27. return(SD_ERROR_ILLEGAL_CMD);
  28. }
  29. send_value=0x40|command; //Add start bit (0) and transmission bit (1)
  30. return_value = SPI_Transfer(send_value,&recv_value);
  31.  
  32. for(index=0;((index<4)&&(return_value==NO_ERROR));index++)
  33. {
  34. send_value=(uint8_t)(argument>>(24-(index*8)));
  35. return_value = SPI_Transfer(send_value,&recv_value);
  36. }
  37.  
  38. if(command==CMD0)
  39. {
  40. send_value=0x95;
  41. }
  42. else if(command==CMD8)
  43. {
  44. send_value=0x87;
  45. }
  46. else //No CRC required
  47. {
  48. send_value=0x01; //Stop bit
  49. }
  50.  
  51. if(return_value==NO_ERROR) //Send the final byte
  52. {
  53. return_value = SPI_Transfer(send_value,&recv_value);
  54. }
  55.  
  56. if(return_value!=NO_ERROR)
  57. {
  58. printf("SD SEND COMMAND ERROR: %0#2x",(uint16_t)return_value);
  59. }
  60.  
  61. return(return_value);
  62. }
  63.  
  64.  
  65. /***********************************************************************
  66. DESC: Recieves SD card response
  67. INPUT: Number of bytes to recieve
  68. RETURNS: Error flags
  69. CAUTION: None
  70. ************************************************************************/
  71. uint8_t SD_receive_response (uint8_t num_bytes, uint8_t * recv_array)
  72. {
  73. uint8_t recv_value;
  74. uint16_t index;
  75. uint8_t return_value=NO_ERROR;
  76. uint8_t timeout=0;
  77.  
  78. do
  79. {
  80. return_value = SPI_Transfer(0xFF,&recv_value);
  81. timeout++;
  82. }while((recv_value==0xFF)&&(timeout!=0)&&(return_value==NO_ERROR));
  83.  
  84. if(return_value==NO_ERROR)
  85. {
  86. if(timeout==0)
  87. {
  88. return_value = SD_ERROR_TIMEOUT;
  89. printf("SD_TIMEOUT_ERROR\n");
  90. }
  91. else if((recv_value & 0xFE)!=0x00) //0x00 and 0x01 are good values
  92. {
  93. *recv_array = recv_value; //return the value to see the error
  94. return_value = SD_ERROR_COMM;
  95. printf("SD COMM ERROR\n");
  96. }
  97. else //Receive the rest of the bytes (if there are more to receive)
  98. {
  99. *recv_array = recv_value; //First received value (R1 response)
  100. if(num_bytes>1)
  101. {
  102. for(index=1;index<num_bytes;index++)
  103. {
  104. return_value=SPI_Transfer(0xFF,&recv_value);
  105. recv_array[index]=recv_value;
  106. }
  107. }
  108. }
  109. }
  110.  
  111. //Send one SPI transfer after response is completely received
  112. if(return_value == NO_ERROR)
  113. {
  114. return_value = SPI_Transfer(0xFF,&recv_value);
  115. }
  116. else
  117. {
  118. SPI_Transfer(0xFF,&recv_value);
  119. }
  120.  
  121. if(return_value != NO_ERROR)
  122. {
  123. printf("SD RECV ERROR:%#0.2x\n",(uint16_t)return_value);
  124. }
  125. return(return_value);
  126. }
  127.  
  128.  
  129. /***********************************************************************
  130. DESC: Recieves SD card response
  131. INPUT: Number of bytes to recieve
  132. RETURNS: Error flags
  133. CAUTION: None
  134. ************************************************************************/
  135. uint8_t SD_Card_Init (void)
  136. {
  137. uint8_t recv_value, return_value = NO_ERROR;
  138. uint8_t index;
  139. uint8_t recv_array[10];
  140. uint8_t high_capacity_support = 1;
  141. uint16_t timeout;
  142.  
  143. printf("SD INIT:\n");
  144. SPI_Set_Bit(SD_nCS);
  145.  
  146. //Send >74 clock cycles
  147. printf(" Sending 80 Clocks\n");
  148. for(index=0;index<10;index++) //Send 74 clock cycles to SD Card
  149. {
  150. SPI_Transfer(0xFF,&recv_value);
  151. }
  152.  
  153. //Send CMD0
  154. printf(" Sending CMD0. ");
  155. SPI_Clear_Bit(SD_nCS);
  156. return_value = SD_send_command(CMD0,0x00);
  157. if(return_value==NO_ERROR)
  158. {
  159. return_value = SD_receive_response (1, recv_array);
  160. }
  161. SPI_Set_Bit(SD_nCS);
  162. printf(" R1:%#2.2bx\n",recv_array[0]);
  163.  
  164. if((return_value==NO_ERROR)&&(recv_array[0] != 0x01))
  165. {
  166. return_value = SD_ERROR;
  167. }
  168.  
  169. //Send CMD8
  170. if(return_value==NO_ERROR)
  171. {
  172. printf(" Sending CMD8. ");
  173. SPI_Clear_Bit(SD_nCS);
  174. return_value = SD_send_command(CMD8,0x000001AA); //SEND_IF_COND cmd, argument 3.6-2.7V
  175. if(return_value==NO_ERROR)
  176. {
  177. return_value = SD_receive_response (5, recv_array); //Receive R7 Response
  178. }
  179. SPI_Set_Bit(SD_nCS);
  180.  
  181. if(return_value==NO_ERROR)
  182. {
  183. printf(" R1:%#2.2bx",recv_array[0]);
  184. if(recv_array[0]==0x05) //If we recieve "illegal command"
  185. {
  186. printf(" Version 1.x SD Card\n");
  187. high_capacity_support = 0;
  188. }
  189. else if(recv_array[0]!=0x01)
  190. {
  191. printf(" Initialization Error %#2.2bx\n",recv_array[0]);
  192. return_value = SD_ERROR_INIT;
  193. }
  194. else //R1 Response is valid
  195. {
  196. printf(" R7:0x");
  197. for(index=1;index<5;index++)
  198. {
  199. printf("%2.2bx",recv_array[index]);
  200. }
  201.  
  202. //Byte 4, lower nibble is voltage
  203. if((recv_array[3]&0x0F) != 0x01)
  204. {
  205. printf(" Voltage Error");
  206. return_value = SD_ERROR_VOLTAGE;
  207. }
  208.  
  209. //Byte 5 is check pattern
  210. else if(recv_array[4] != 0xAA)
  211. {
  212. printf(" Check Pattern Error");
  213. return_value = SD_ERROR_VOLTAGE;
  214. }
  215.  
  216. printf("\n");
  217. }
  218. }
  219. }//End CMD8
  220.  
  221. //Send CMD58
  222. if(return_value==NO_ERROR)
  223. {
  224. printf(" Sending CMD58.");
  225. SPI_Clear_Bit(SD_nCS);
  226. return_value = SD_send_command(CMD58,0x00); //Send "Read OCR" command
  227. if(return_value==NO_ERROR)
  228. {
  229. return_value = SD_receive_response (5, recv_array); //Receive R3 Response
  230. }
  231.  
  232. SPI_Set_Bit(SD_nCS);
  233.  
  234. if(return_value==NO_ERROR)
  235. {
  236. printf(" R1:%#2.2bx",recv_array[0]);
  237. if(recv_array[0]!=0x01)
  238. {
  239. printf(" Initialization Error %#2.2bx\n",recv_array[0]);
  240. return_value = SD_ERROR_INIT;
  241. }
  242. else //R1 Response is valid, check OCR
  243. {
  244. printf(" OCR:0x");
  245. for(index=1;index<5;index++)
  246. {
  247. printf("%2.2bx",recv_array[index]);
  248. }
  249. if((recv_array[2]&0xFC) != 0xFC) //Check volatge 3.0-3.6V
  250. {
  251. printf(" Voltage Error");
  252. return_value = SD_ERROR_VOLTAGE;
  253. }
  254. else if(((recv_array[0]&0x80)==0x80)) //Check card capacity
  255. {
  256. //Card powered up, and low capacity
  257. printf(" Low Capacity SD Card");
  258. high_capacity_support = 0;
  259. }
  260. printf("\n");
  261. }
  262. }
  263. }//End CMD58
  264.  
  265.  
  266. //Send ACMD41
  267. if(return_value==NO_ERROR)
  268. {
  269. timeout=0;
  270.  
  271. printf(" Sending CMD58.");
  272. SPI_Clear_Bit(SD_nCS);
  273. do
  274. {
  275. SD_send_command(CMD55,0x00);
  276. SD_receive_response (1, recv_array); //Receive R1 Response
  277. SD_send_command(CMD41,(0x00|(high_capacity_support<<30)));
  278. SD_receive_response (1, recv_array); //Receive R1 Response
  279. timeout++;
  280. }while((timeout!=0)&&(recv_array[0]!=0x00));
  281. SPI_Set_Bit(SD_nCS);
  282.  
  283.  
  284. printf(" R1:%#2.2bx",recv_array[0]);
  285. if(recv_array[0]!=0x01)
  286. {
  287. printf(" Initialization Error %#2.2bx\n",recv_array[0]);
  288. return_value = SD_ERROR_INIT;
  289. }
  290. else //R1 Response is valid, check OCR
  291. {
  292. printf(" OCR:0x");
  293. for(index=1;index<5;index++)
  294. {
  295. printf("%2.2bx",recv_array[index]);
  296. }
  297. if((recv_array[2]&0xFC) != 0xFC) //Check volatge 3.0-3.6V
  298. {
  299. printf(" Voltage Error");
  300. return_value = SD_ERROR_VOLTAGE;
  301. }
  302. else if(((recv_array[0]&0x80)==0x80)) //Check card capacity
  303. {
  304. //Card powered up, and low capacity
  305. printf(" Low Capacity SD Card");
  306. high_capacity_support = 0;
  307. }
  308. printf("\n");
  309. }
  310. }//End ACMD41
  311.  
  312. return(return_value);
  313. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement