📄 sdspihal.c
字号:
return SD_ERR_TIMEOUT_WRITE; /* 写入超时 write time out */
else
return SD_NO_ERR; /* 写入正确 write right */
}
/*******************************************************************************************************************
** 函数名称: void SD_StopMultiToken() Name: void SD_StopMultiToken(void)
** 功能描述: 发送多块写停止令牌 Function: send the token that stop multiple block write
** 输 入: 无 Input: NULL
** 输 出: 无 Output: NULL
********************************************************************************************************************/
void SdHal_StopMultiToken(sd_struct *sds)
{
SdHal_SPI_CSAssert(sds);
SdHal_SPISendByte(sds, 0xFF); /* 先发送8个clock send 8 clock first */
SdHal_SPISendByte(sds, SD_TOK_STOP_MULTI); /* 发送停止数据传输令牌 send stop transmission token */
SdHal_SPIRecByte(sds);
SdHal_SPI_CSDeassert(sds);
}
/********************************************************************************************************************
** 函数名称: void SD_WaitBusy() Name: void SD_WaitBusy()
** 功能描述: 查询SD卡是否处于忙状态 Function: poll SD Card wheather it is busy
** 输 入: INT32U waittype: 超时类型 Input: INT32U timeout: time out type
** 输 出: 0: 未超时 >0: 错误码 Output: 0: not time out > 0: error code
*********************************************************************************************************************/
INT8U SdHal_WaitBusy(sd_struct *sds, INT8U waittype)
{
INT32U timeout, i = 0;
INT8U tmp;
if (waittype == SD_WAIT_WRITE)
timeout = sds->timeout_write; /* 等待类型为写操作 wait type is write operation */
else
timeout = sds->timeout_erase; /* 等待类型为擦除操作 wait type is erase operation */
#if SD_UCOSII_EN
timeout = SD_UCOSII_SMALLWAIT; /* 很少的等待时间 small wait time */
#endif
SdHal_SPI_CSAssert(sds);
do
{ /* 等待忙结束 wait for being busy end */
tmp = SdHal_SPIRecByte(sds);
i++;
}while ((tmp != 0xFF) && (i < timeout)); /* 忙时收到的值为0 always receive 0 when card is busy */
#if SD_UCOSII_EN
if (i >= timeout)
{ /* 很少等待后卡仍忙, after small wait, card is still busy */
if (waittype == SD_WAIT_WRITE)
timeout = sds->timeout_write;
else
timeout = sds->timeout_erase;
i = 0;
do
{
OSTimeDly(1); /* 操作系统挂起1 tick OS suspend 1 tick */
tmp = SdHal_SPIRecByte(sds);
i++;
}while ((tmp != 0xFF) && (i < timeout)); /* 忙时收到的值为0 always receive 0 when card is busy */
}
#endif
if(i < timeout)
tmp = SD_NO_ERR; /* 返回0,表示没超时 return 0 indicate that operation is not time out */
else
tmp = SD_ERR_TIMEOUT_WAIT; /* 返回错误码,表示超时 return error code indicate that operation is time out */
SdHal_SPISendByte(sds, 0xFF);
SdHal_SPI_CSDeassert(sds);
return tmp; /* 返回执行结果 */
}
/********************************************************************************************************************
** 函数名称: void SD_SPIDelay() Name: void SD_SPIDelay()
** 功能描述: SPI总线延时 Function: SPI Bus delay
** 输 入: INT8U value: 延时值,不超过255 Input: INT8U value : delay value,do not beyond 255
** 输 出: 无 Output: NULL
*********************************************************************************************************************/
void SdHal_SPIDelay(sd_struct *sds, INT8U value)
{
INT8U i;
for (i = 0; i < value; i++)
SdHal_SPISendByte(sds, 0xFF); /* 发送0xFF clock out 0xFF */
}
/**************************************************************
读写SD卡的SPI接口函数: SPI接口设置,发送/接收字节函数
**************************************************************/
/*******************************************************************************************************************
** 函数名称: void SD_Power() Name: void SD_Power()
** 功能描述: 对卡先下电,再上电 Function: turn off the card's power, and turn on
** 输 入: 无 Input: NULL
** 输 出: 无 Output: NULL
********************************************************************************************************************/
void SD_Power(void)
{
INT32U i;
SD_POWER_GPIO();
SD_POWER_OUT();
SD_POWER_OFF(); /* 关闭 SD 卡电源 turn off power of sd card */
SPI_SCK_GPIO();
SPI_SCK_OUT();
SPI_SCK_CLR(); /* SCK 引脚置低 set SCK to zero */
SPI_MISO_GPIO();
SPI_MISO_OUT();
SPI_MISO_CLR(); /* MISO 引脚置低 set MISO to zero */
SPI_MOSI_GPIO();
SPI_MOSI_OUT();
SPI_MOSI_CLR(); /* MOSI 引脚置低 set MOSI to zero */
SPI_CS_GPIO();
SPI_CS_OUT();
SPI_CS_CLR(); /* CS 引脚置低 set CS to zero */
for(i = 0; i < 0x9000; i++); /* 关闭电源延时 delay after turn off power of sd card */
SD_POWER_ON(); /* 打开 SD 卡电源 turn on power of sd card */
}
/*******************************************************************************************************************
** 函数名称: void SD_HardWareInit() Name: void SD_HardWareInit()
** 功能描述: 初始化访问SD卡的硬件条件 Function: initialize the hardware condiction that access sd card
** 输 入: 无 Input: NULL
** 输 出: 无 Output: NULL
********************************************************************************************************************/
INT8U SdHal_Initialize(sd_struct *sds)
{
SD_Power(); /* 对卡先下电,再上电 */
SPI_INIT(); /* 初始化SPI接口 */
SD_INSERT_GPIO();
SD_INSERT_IN(); /* 检测卡完全插入口为输入口 */
SD_WP_GPIO();
SD_WP_IN(); /* 写保护检测口为输入口 */
SPI_CS_SET(); /* CS置高 */
SdHal_SetMCIClock(sds, SD_RATE_SLOW); /* 设置SPI频率小于等于400kHZ */
SPI_SPCR = (0x01 << 4) + (0x01 << 5); /* 设置SPI接口模式, MSTR = 1,CPOL = 1,CPHA = 0,LSBF=0 */
return SD_NO_ERR;
}
/*******************************************************************************************************************
** 函数名称: SdHal_SetMCIClock()
**
** 功能描述: 设置读写SD/MMC卡时钟
**
** 输 入: sd_struct *sds : 卡信息结构体
** INT32U ClockRate: 要求的时钟速度. 取值SD_RATE_SLOW 时, 设置访问卡速度小于 400KHz
** 取值SD_RATE_NORMAL 时, 设置访问卡速度为卡的最大速度或主控器的最大速度
** 输 出: 无
**
** 返 回 值: 0: 正确 >0: 错误码, 见 sddriver.h 文件
**
** 注 意: 本函数有责任在ClockRate取不同的值时, 计算出相应的 sds->clkval 值, 必须大于0.
**
********************************************************************************************************************/
void SdHal_SetMCIClock(sd_struct *sds, INT32U ClockRate)
{
if (ClockRate == SD_RATE_SLOW)
{
SPI_SPCCR = 128; /* 设置SPI时钟分频值为128 */
sds->host_clkval = Fpclk / 128;
}
else if (ClockRate == SD_RATE_NORMAL)
{
SPI_SPCCR = 8; /* 设置SPI时钟分频值为8 */
sds->host_clkval = Fpclk / 8;
}
}
/*******************************************************************************************************************
** 函数名称: void SPI_SendByte() Name: void SPI_SendByte()
** 功能描述: 通过SPI接口发送一个字节 Function: send a byte by SPI interface
** 输 入: INT8U byte: 发送的字节 Input: INT8U byte: the byte that will be send
** 输 出: 无 Output: NULL
********************************************************************************************************************/
void SdHal_SPISendByte(sd_struct *sds, INT8U byte)
{
INT8U temp;
SPI_SPDR = byte; /* 发送数据放入SPI数据寄存器 */
while(0 == (SPI_SPSR & 0x80)); /* 等待SPIF置位,即等待数据发送完毕 */
/* wait for SPIF being set, that is, wait for finishing of data being send */
temp = SPI_SPDR;
}
/*******************************************************************************************************************
** 函数名称: INT8U SPI_RecByte() Name: INT8U SPI_RecByte()
** 功能描述: 从SPI接口接收一个字节 Function: receive a byte from SPI interface
** 输 入: 无 Input: NULL
** 输 出: 收到的字节 Output: the byte that be received
********************************************************************************************************************/
INT8U SdHal_SPIRecByte(sd_struct *sds)
{
SPI_SPDR = 0xFF;
while(0 == (SPI_SPSR & 0x80)); /* 等待SPIF置位,即等待收到数据 */
/* wait for SPIF being set, that is, wait for being received data */
return(SPI_SPDR); /* 读取收到的字节 read the byte received */
}
/*******************************************************************************************************************
** 函数名称: void SPI_CS_Assert() Name: void SPI_CS_Assert()
** 功能描述: 片选SPI从机 Function: select the SPI slave
** 输 入: 无 Input: NULL
** 输 出: 无 Output: NULL
********************************************************************************************************************/
void SdHal_SPI_CSAssert(sd_struct *sds)
{
SPI_CS_CLR(); /* 片选SPI从机 select the SPI slave */
}
/*******************************************************************************************************************
** 函数名称: void SPI_CS_Deassert() Name: void SPI_CS_Deassert()
** 功能描述: 不片选SPI从机 Function: not select the SPI slave
** 输 入: 无 Input: NULL
** 输 出: 无 Output: NULL
********************************************************************************************************************/
void SdHal_SPI_CSDeassert(sd_struct *sds)
{
SPI_CS_SET(); /* 不片选SPI从机 not select the SPI slave */
}
/*******************************************************************************************************************
** 函数名称: void SD_ChkCard() Name: void SD_ChkCard()
** 功能描述: 检测卡是否完全插入 Function: check weather card is insert entirely
** 输 入: 无 Input: NULL
** 输 出: 1: 卡完全插入 0: 卡没有完全插入 Output: 1: insert entirely 0: not insert entirely
********************************************************************************************************************/
INT8U SdHal_CheckCard(sd_struct *sds)
{
if (SD_INSERT_STATUS() != 0)
return 0; /* 未完全插入 not insert entirely */
else
return 1; /* 完全插入 insert entirely */
}
/*******************************************************************************************************************
** 函数名称: void SD_ChkCardWP() Name: void SD_ChkCardWP()
** 功能描述: 检测卡写保护 Function: check weather card is write protect
** 输 入: 无 Input: NULL
** 输 出: 1: 卡已写保护 0: 卡未写保护 Output: 1: insert write protect 0: not write protect
********************************************************************************************************************/
INT8U SdHal_CheckCardWP(sd_struct *sds)
{
if (SD_WP_STATUS() != 0)
return 1; /* 卡写保护 */
else
return 0; /* 卡未写保护 */
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -