updating with more commands

stable
penguin 3 years ago
parent 68e738db2b
commit 8b6ad41411

File diff suppressed because it is too large Load Diff

@ -1 +0,0 @@
penguin@penguin-arch-home.4569:1608044795

@ -2,42 +2,22 @@
#include "sd_mmc_intf.h"
#include <assert.h>
static bool sd_mmc_check_cd(void)
{
switch(SD_MMC_CD_MODE)
{
case SD_MMC_CD_MODE_UNUSED:
{
// Always assume the card is detected since we aren't using this function
return true;
}break;
case SD_MMC_CD_MODE_SYNC:
{
return SD_MMC_INTF_CHECK_CD();
}break;
case SD_MMC_CD_MODE_ASYNC:
{
// Unimplemented
return false;
}break;
default:
{
return false;
}
}
return false;
}
// send 80 clock cycles
static void sd_mmc_send_clock()
{
uint8_t i;
uint8_t dummy = 0xFF;
for(i = 0; i < 10; i++)
{
SD_MMC_INTF_WRITE(&dummy, 1);
}
}
// Functions used to interact with the SD card
static sd_mmc_err_t sd_mmc_power_up_sequence();
static sd_mmc_err_t sd_mmc_idle_sequence();
static sd_mmc_err_t sd_mmc_if_sequence();
static sd_mmc_err_t sd_mmc_read_ocr(uint8_t* res);
static sd_mmc_err_t sd_mmc_read_res1(uint8_t* res1);
static sd_mmc_err_t sd_mmc_read_res7(uint8_t* res7);
static sd_mmc_err_t sd_mmc_read_res3(uint8_t* res3);
static bool sd_mmc_check_cd(void);
static void sd_mmc_send_clock(void);
// Functions used for debugging
static void sd_mmc_print_err(sd_mmc_err_t err);
static void sd_mmc_print_res1(uint8_t res);
static void sd_mmc_print_res7(const uint8_t* const res);
sd_mmc_err_t sd_mmc_init(void)
{
@ -45,34 +25,39 @@ sd_mmc_err_t sd_mmc_init(void)
do
{
// Hardware initialize
if(0 != SD_MMC_INTF_INIT())
{
ret = SD_MMC_INIT_FAILURE;
break;
}
// power up sequence
delay_ms(1);
sd_mmc_send_clock();
// go idle
sd_mmc_select(0, 0, 0, true);
if(0 != sd_mmc_send_command(CMD0, CMD0_ARG, CMD0_CRC))
// Power up sd card sequence
if((ret != sd_mmc_power_up_sequence()) != SD_MMC_SUCCESS)
{
ret = SD_MMC_ERR_COMM;
break;
}
uint8_t res1_ret = 0xFF;
if(0 != sd_mmc_read_res1(&res1_ret))
// go idle
if((ret != sd_mmc_idle_sequence()) != SD_MMC_SUCCESS)
{
ret = SD_MMC_ERR_COMM;
break;
}
sd_mmc_deselect(0);
// interface sequence
if((ret != sd_mmc_if_sequence()) != SD_MMC_SUCCESS)
{
break;
}
printf("res1: 0x%02x\n", res1_ret);
}while(0);
if(ret != SD_MMC_SUCCESS)
{
printf("Error initializing SD Card: ");
sd_mmc_print_err(ret);
}
return ret;
}
@ -92,7 +77,6 @@ sd_mmc_err_t sd_mmc_select(uint8_t slot, uint32_t clock, uint8_t bus_width, bool
sd_mmc_err_t ret = SD_MMC_SUCCESS;
SD_MMC_INTF_SELECT_DEVICE();
return ret;
}
sd_mmc_err_t sd_mmc_send_command(uint8_t cmd, uint32_t arg, uint8_t crc)
@ -113,7 +97,7 @@ sd_mmc_err_t sd_mmc_send_command(uint8_t cmd, uint32_t arg, uint8_t crc)
}
sd_mmc_err_t sd_mmc_read_res1(uint8_t* ret_byte)
sd_mmc_err_t sd_mmc_read_res1(uint8_t* byte)
{
sd_mmc_err_t ret = SD_MMC_SUCCESS;
@ -121,11 +105,263 @@ sd_mmc_err_t sd_mmc_read_res1(uint8_t* ret_byte)
do
{
i++;
SD_MMC_INTF_READ(ret_byte, 1);
}while(i <= 8 && *ret_byte == 0xFF);
if(*ret_byte == 0xFF)
SD_MMC_INTF_READ(byte, 1);
}while(i <= 8 && *byte == 0xFF);
if(*byte == 0xFF)
{
return SD_MMC_TIMEOUT;
}
return ret;
}
sd_mmc_err_t sd_mmc_read_res7(uint8_t* res7)
{
sd_mmc_err_t ret = SD_MMC_SUCCESS;
do
{
if(5 != SD_MMC_INTF_READ(res7, 5))
{
ret = SD_MMC_ERR_COMM;
break;
}
if(res7[0] > 1)
{
// handle this error better later
ret = SD_MMC_ERR_COMM;
break;
}
}while(0);
return ret;
}
sd_mmc_err_t sd_mmc_read_res3(uint8_t* res3)
{
sd_mmc_err_t ret = SD_MMC_SUCCESS;
do
{
if(5 != SD_MMC_INTF_READ(res3, 5))
{
ret = SD_MMC_ERR_COMM;
break;
}
if(res3[0] > 1)
{
// handle this error better later
ret = SD_MMC_ERR_COMM;
break;
}
}while(0);
return ret;
}
sd_mmc_err_t sd_mmc_power_up_sequence()
{
sd_mmc_err_t ret = SD_MMC_SUCCESS;
// power up sequence
delay_ms(1);
sd_mmc_send_clock();
return ret;
}
sd_mmc_err_t sd_mmc_idle_sequence()
{
sd_mmc_err_t ret = SD_MMC_SUCCESS;
uint8_t res1 = 0xFF;
sd_mmc_select(0, 0, 0, false);
do
{
sd_mmc_select(0, 0, 0, true);
if((ret != sd_mmc_send_command(CMD0, CMD0_ARG, CMD0_CRC)) != SD_MMC_SUCCESS)
{
break;
}
if((ret != sd_mmc_read_res1(&res1)) != SD_MMC_SUCCESS)
{
break;
}
sd_mmc_print_res1(res1);
}while(0);
sd_mmc_deselect(0);
return ret;
}
sd_mmc_err_t sd_mmc_if_sequence()
{
sd_mmc_err_t ret = SD_MMC_SUCCESS;
uint8_t res7[5];
sd_mmc_select(0, 0, 0, false);
do
{
if((ret = sd_mmc_send_command(CMD8, CMD8_ARG, CMD8_CRC)) != SD_MMC_SUCCESS)
{
break;
}
if((ret = sd_mmc_read_res7(res7)) != SD_MMC_SUCCESS)
{
break;
}
sd_mmc_print_res7(res7);
}while(0);
sd_mmc_deselect(0);
return ret;
}
void sd_mmc_print_err(sd_mmc_err_t err)
{
switch(err)
{
case SD_MMC_SUCCESS:
{
printf("%s", "SD_MMC_SUCCESS\n");
}break;
case SD_MMC_FAILURE:
{
printf("%s", "SD_MMC_FAILURE\n");
}break;
case SD_MMC_INIT_ONGOING:
{
printf("%s", "SD_MMC_INIT_ONGOING\n");
}break;
case SD_MMC_ERR_NO_CARD:
{
printf("%s", "SD_MMC_ERR_NO_CARD\n");
}
case SD_MMC_ERR_UNUSABLE:
{
printf("%s", "SD_MMC_UNUSABLE\n");
}break;
case SD_MMC_ERR_SLOT:
{
printf("%s", "SD_MMC_ERR_SLOT\n");
}break;
case SD_MMC_ERR_COMM:
{
printf("%s", "SD_MMC_ERR_COMM\n");
}break;
case SD_MMC_ERR_PARAM:
{
printf("%s", "SD_MMC_ERR_PARAM\n");
}break;
case SD_MMC_ERR_WP:
{
printf("%s", "SD_MMC_ERR_WP\n");
}break;
case SD_MMC_INIT_FAILURE:
{
printf("%s", "SD_MMC_INIT_FAILURE\n");
}break;
case SD_MMC_TIMEOUT:
{
printf("%s", "SD_MMC_TIMEOUT\n");
}break;
default:
{
printf("%s", "UNKNOWN ERROR");
}
}
}
void sd_mmc_print_res1(uint8_t res)
{
if(res & 0b10000000)
{ printf("\tError: MSB = 1\r\n"); return; }
if(res == 0)
{ printf("\tCard Ready\r\n"); return; }
if(PARAM_ERROR(res))
printf("\tParameter Error\r\n");
if(ADDR_ERROR(res))
printf("\tAddress Error\r\n");
if(ERASE_SEQ_ERROR(res))
printf("\tErase Sequence Error\r\n");
if(CRC_ERROR(res))
printf("\tCRC Error\r\n");
if(ILLEGAL_CMD(res))
printf("\tIllegal Command\r\n");
if(ERASE_RESET(res))
printf("\tErase Reset Error\r\n");
if(IN_IDLE(res))
printf("\tIn Idle State\r\n");
}
void sd_mmc_print_res7(const uint8_t* const res)
{
sd_mmc_print_res1(res[0]);
if(res[0] > 1) return;
printf("\tCommand Version: 0x%02x\n", CMD_VER(res[1]));
printf("\tVoltage Accepted: %s\n",
(res[3] == VOLTAGE_ACC_27_33) ? "2.7-3.6V"
: (res[3] == VOLTAGE_ACC_LOW) ? "LOW VOLTAGE"
: (res[3] == VOLTAGE_ACC_RES1 || res[3] == VOLTAGE_ACC_RES2) ? "RESERVED"
: "NOT DEFINED");
printf("\tEcho: 0x%02x\n", res[4]);
}
bool sd_mmc_check_cd(void)
{
switch(SD_MMC_CD_MODE)
{
case SD_MMC_CD_MODE_UNUSED:
{
// Always assume the card is detected since we aren't using this function
return true;
}break;
case SD_MMC_CD_MODE_SYNC:
{
return SD_MMC_INTF_CHECK_CD();
}break;
case SD_MMC_CD_MODE_ASYNC:
{
// Unimplemented
return false;
}break;
default:
{
return false;
}
}
return false;
}
void sd_mmc_send_clock()
{
uint8_t i;
uint8_t dummy = 0xFF;
for(i = 0; i < 10; i++)
{
SD_MMC_INTF_WRITE(&dummy, 1);
}
}
sd_mmc_err_t sd_mmc_read_ocr(uint8_t* res)
{
sd_mmc_err_t ret = SD_MMC_SUCCESS;
uint8_t res3[5];
sd_mmc_select(0, 0, 0, false);
do
{
if((ret = sd_mmc_send_command(CMD58, CMD58_ARG, CMD58_CRC)) != SD_MMC_SUCCESS)
{
break;
}
if((ret = sd_mmc_read_res3(res3)) != SD_MMC_SUCCESS)
{
break;
}
}while(0);
sd_mmc_deselect(0);
return ret;
}

@ -12,17 +12,17 @@ typedef enum sd_mmc_mode_t
typedef enum sd_mmc_err_t
{
SD_MMC_SUCCESS = 0,
SD_MMC_FAIL = 1,
SD_MMC_INIT_ONGOING = 2,
SD_MMC_ERR_NO_CARD = 3,
SD_MMC_ERR_UNUSABLE = 4,
SD_MMC_ERR_SLOT = 5,
SD_MMC_ERR_COMM = 6,
SD_MMC_ERR_PARAM = 7,
SD_MMC_ERR_WP = 8,
SD_MMC_INIT_FAILURE = 9,
SD_MMC_TIMEOUT = 10
SD_MMC_SUCCESS = 0,
SD_MMC_FAILURE = 1,
SD_MMC_INIT_ONGOING = 2,
SD_MMC_ERR_NO_CARD = 3,
SD_MMC_ERR_UNUSABLE = 4,
SD_MMC_ERR_SLOT = 5,
SD_MMC_ERR_COMM = 6,
SD_MMC_ERR_PARAM = 7,
SD_MMC_ERR_WP = 8,
SD_MMC_INIT_FAILURE = 9,
SD_MMC_TIMEOUT = 10,
} sd_mmc_err_t;
// The card detect function can be unused, used regularly, or via interrupt.
@ -41,8 +41,14 @@ sd_mmc_err_t sd_mmc_init(void);
sd_mmc_err_t sd_mmc_select(uint8_t slot, uint32_t clock, uint8_t bus_width, bool high_speed);
sd_mmc_err_t sd_mmc_deselect(uint8_t slot);
sd_mmc_err_t sd_mmc_send_command(uint8_t cmd, uint32_t arg, uint8_t crc);
sd_mmc_err_t sd_mmc_read_res1(uint8_t* ret_byte);
#define PARAM_ERROR(x) (x & 0b01000000)
#define ADDR_ERROR(x) (x & 0b00100000)
#define ERASE_SEQ_ERROR(x) (x & 0b00010000)
#define CRC_ERROR(x) (x & 0b00001000)
#define ILLEGAL_CMD(x) (x & 0b00000100)
#define ERASE_RESET(x) (x & 0b00000010)
#define IN_IDLE(x) (x & 0b00000001)
#define SD_MMC_CD_MODE SD_MMC_CD_MODE_SYNC
@ -54,7 +60,23 @@ sd_mmc_err_t sd_mmc_read_res1(uint8_t* ret_byte);
#define CMD0_ARG 0x00000000
#define CMD0_CRC 0x94
#define CMD8 8
#define CMD8_ARG 0x000001AA
#define CMD8_CRC 0x86
#define CMD58 58
#define CMD58_ARG 0x00000000
#define CMD58_CRC 0x00
#define UNUSED(v) (void)(v)
#define CMD_VER(X) ((X >> 4) & 0xF0)
#define VOL_ACC(X) (X & 0x1F)
#define VOLTAGE_ACC_27_33 0b00000001
#define VOLTAGE_ACC_LOW 0b00000010
#define VOLTAGE_ACC_RES1 0b00000100
#define VOLTAGE_ACC_RES2 0b00001000
#endif

Loading…
Cancel
Save