Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- SPI_Hardware.c
- 10/14/2019
- Ron Mikulecky
- Elijah Whitmire
- */
- #include "Main.h"
- #include "SPI.h"
- #include "SPI_Hardware.h"
- #include <stdio.h>
- /***********************************************************************
- DESC: Sends SD card command over SPI
- INPUT: Command number, 32bit argument
- RETURNS: SD or SPI Error flags
- CAUTION: None
- ************************************************************************/
- uint8_t SD_send_command (uint8_t command, uint32_t argument)
- {
- uint8_t send_value, recv_value, return_value;
- uint8_t index;
- if(command>=64)//Command out of range
- {
- return(SD_ERROR_ILLEGAL_CMD);
- }
- send_value=0x40|command; //Add start bit (0) and transmission bit (1)
- return_value = SPI_Transfer(send_value,&recv_value);
- for(index=0;((index<4)&&(return_value==NO_ERROR));index++)
- {
- send_value=(uint8_t)(argument>>(24-(index*8)));
- return_value = SPI_Transfer(send_value,&recv_value);
- }
- if(command==CMD0)
- {
- send_value=0x95;
- }
- else if(command==CMD8)
- {
- send_value=0x87;
- }
- else //No CRC required
- {
- send_value=0x01; //Stop bit
- }
- if(return_value==NO_ERROR) //Send the final byte
- {
- return_value = SPI_Transfer(send_value,&recv_value);
- }
- if(return_value!=NO_ERROR)
- {
- printf("SD SEND COMMAND ERROR: %0#2x",(uint16_t)return_value);
- }
- return(return_value);
- }
- /***********************************************************************
- DESC: Recieves SD card response
- INPUT: Number of bytes to recieve
- RETURNS: Error flags
- CAUTION: None
- ************************************************************************/
- uint8_t SD_receive_response (uint8_t num_bytes, uint8_t * recv_array)
- {
- uint8_t recv_value;
- uint16_t index;
- uint8_t return_value=NO_ERROR;
- uint8_t timeout=0;
- do
- {
- return_value = SPI_Transfer(0xFF,&recv_value);
- timeout++;
- }while((recv_value==0xFF)&&(timeout!=0)&&(return_value==NO_ERROR));
- if(return_value==NO_ERROR)
- {
- if(timeout==0)
- {
- return_value = SD_ERROR_TIMEOUT;
- printf("SD_TIMEOUT_ERROR\n");
- }
- else if((recv_value & 0xFE)!=0x00) //0x00 and 0x01 are good values
- {
- *recv_array = recv_value; //return the value to see the error
- return_value = SD_ERROR_COMM;
- printf("SD COMM ERROR\n");
- }
- else //Receive the rest of the bytes (if there are more to receive)
- {
- *recv_array = recv_value; //First received value (R1 response)
- if(num_bytes>1)
- {
- for(index=1;index<num_bytes;index++)
- {
- return_value=SPI_Transfer(0xFF,&recv_value);
- recv_array[index]=recv_value;
- }
- }
- }
- }
- //Send one SPI transfer after response is completely received
- if(return_value == NO_ERROR)
- {
- return_value = SPI_Transfer(0xFF,&recv_value);
- }
- else
- {
- SPI_Transfer(0xFF,&recv_value);
- }
- if(return_value != NO_ERROR)
- {
- printf("SD RECV ERROR:%#0.2x\n",(uint16_t)return_value);
- }
- return(return_value);
- }
- /***********************************************************************
- DESC: Recieves SD card response
- INPUT: Number of bytes to recieve
- RETURNS: Error flags
- CAUTION: None
- ************************************************************************/
- uint8_t SD_Card_Init (void)
- {
- uint8_t recv_value, return_value = NO_ERROR;
- uint8_t index;
- uint8_t recv_array[10];
- uint8_t high_capacity_support = 1;
- uint16_t timeout;
- printf("SD INIT:\n");
- SPI_Set_Bit(SD_nCS);
- //Send >74 clock cycles
- printf(" Sending 80 Clocks\n");
- for(index=0;index<10;index++) //Send 74 clock cycles to SD Card
- {
- SPI_Transfer(0xFF,&recv_value);
- }
- //Send CMD0
- printf(" Sending CMD0. ");
- SPI_Clear_Bit(SD_nCS);
- return_value = SD_send_command(CMD0,0x00);
- if(return_value==NO_ERROR)
- {
- return_value = SD_receive_response (1, recv_array);
- }
- SPI_Set_Bit(SD_nCS);
- printf(" R1:%#2.2bx\n",recv_array[0]);
- if((return_value==NO_ERROR)&&(recv_array[0] != 0x01))
- {
- return_value = SD_ERROR;
- }
- //Send CMD8
- if(return_value==NO_ERROR)
- {
- printf(" Sending CMD8. ");
- SPI_Clear_Bit(SD_nCS);
- return_value = SD_send_command(CMD8,0x000001AA); //SEND_IF_COND cmd, argument 3.6-2.7V
- if(return_value==NO_ERROR)
- {
- return_value = SD_receive_response (5, recv_array); //Receive R7 Response
- }
- SPI_Set_Bit(SD_nCS);
- if(return_value==NO_ERROR)
- {
- printf(" R1:%#2.2bx",recv_array[0]);
- if(recv_array[0]==0x05) //If we recieve "illegal command"
- {
- printf(" Version 1.x SD Card\n");
- high_capacity_support = 0;
- }
- else if(recv_array[0]!=0x01)
- {
- printf(" Initialization Error %#2.2bx\n",recv_array[0]);
- return_value = SD_ERROR_INIT;
- }
- else //R1 Response is valid
- {
- printf(" R7:0x");
- for(index=1;index<5;index++)
- {
- printf("%2.2bx",recv_array[index]);
- }
- //Byte 4, lower nibble is voltage
- if((recv_array[3]&0x0F) != 0x01)
- {
- printf(" Voltage Error");
- return_value = SD_ERROR_VOLTAGE;
- }
- //Byte 5 is check pattern
- else if(recv_array[4] != 0xAA)
- {
- printf(" Check Pattern Error");
- return_value = SD_ERROR_VOLTAGE;
- }
- printf("\n");
- }
- }
- }//End CMD8
- //Send CMD58
- if(return_value==NO_ERROR)
- {
- printf(" Sending CMD58.");
- SPI_Clear_Bit(SD_nCS);
- return_value = SD_send_command(CMD58,0x00); //Send "Read OCR" command
- if(return_value==NO_ERROR)
- {
- return_value = SD_receive_response (5, recv_array); //Receive R3 Response
- }
- SPI_Set_Bit(SD_nCS);
- if(return_value==NO_ERROR)
- {
- printf(" R1:%#2.2bx",recv_array[0]);
- if(recv_array[0]!=0x01)
- {
- printf(" Initialization Error %#2.2bx\n",recv_array[0]);
- return_value = SD_ERROR_INIT;
- }
- else //R1 Response is valid, check OCR
- {
- printf(" OCR:0x");
- for(index=1;index<5;index++)
- {
- printf("%2.2bx",recv_array[index]);
- }
- if((recv_array[2]&0xFC) != 0xFC) //Check volatge 3.0-3.6V
- {
- printf(" Voltage Error");
- return_value = SD_ERROR_VOLTAGE;
- }
- else if(((recv_array[0]&0x80)==0x80)) //Check card capacity
- {
- //Card powered up, and low capacity
- printf(" Low Capacity SD Card");
- high_capacity_support = 0;
- }
- printf("\n");
- }
- }
- }//End CMD58
- //Send ACMD41
- if(return_value==NO_ERROR)
- {
- timeout=0;
- printf(" Sending CMD58.");
- SPI_Clear_Bit(SD_nCS);
- do
- {
- SD_send_command(CMD55,0x00);
- SD_receive_response (1, recv_array); //Receive R1 Response
- SD_send_command(CMD41,(0x00|(high_capacity_support<<30)));
- SD_receive_response (1, recv_array); //Receive R1 Response
- timeout++;
- }while((timeout!=0)&&(recv_array[0]!=0x00));
- SPI_Set_Bit(SD_nCS);
- printf(" R1:%#2.2bx",recv_array[0]);
- if(recv_array[0]!=0x01)
- {
- printf(" Initialization Error %#2.2bx\n",recv_array[0]);
- return_value = SD_ERROR_INIT;
- }
- else //R1 Response is valid, check OCR
- {
- printf(" OCR:0x");
- for(index=1;index<5;index++)
- {
- printf("%2.2bx",recv_array[index]);
- }
- if((recv_array[2]&0xFC) != 0xFC) //Check volatge 3.0-3.6V
- {
- printf(" Voltage Error");
- return_value = SD_ERROR_VOLTAGE;
- }
- else if(((recv_array[0]&0x80)==0x80)) //Check card capacity
- {
- //Card powered up, and low capacity
- printf(" Low Capacity SD Card");
- high_capacity_support = 0;
- }
- printf("\n");
- }
- }//End ACMD41
- return(return_value);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement