?? sdspihal.c
字號:
/****************************************Copyright (c)**************************************************
** Guangzhou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: sdspihal.c
** Last modified Date: 2007-07-08
** Last Version: V3.0
** Descriptions: SD/MMC卡讀寫軟件包: 硬件抽象層 -- SPI模式
**
**
**------------------------------------------------------------------------------------------------------
** Created by: Ming Yuan Zheng
** Created date: 2005-1-6
** Version: V1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by: Ming Yuan Zheng
** Modified date: 2007-07-08
** Version: V3.0
** Descriptions: 1. 將SPI_Clk400k()和SPI_ClkToMax()兩函數合并為一個函數SdSpiHal_SetMCIClock()
** 2. 多數函數名以 SdSpiHal_ 作為開頭
** 3. 增加對多卡的支持
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "sdconfig.h"
#if (!SDBUS_MODE_EN)
/***************************************************************************
讀寫SD/MMC卡的SPI接口函數: SPI 初始化, SPI時鐘設置, 發送/接收字節函數
***************************************************************************/
/*******************************************************************************************************************
** 函數名稱: SD_Power()
**
** 功能描述: 對卡先下電,再上電
**
** 輸 入: 無
**
** 輸 出: 無
**
** 返 回 值: 無
********************************************************************************************************************/
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 */
}
/*******************************************************************************************************************
** 函數名稱: SdSpiHal_Initialize()
**
** 功能描述: 初始化訪問卡的硬件條件
**
** 輸 入: sd_struct *sds: 卡信息結構體, 該函數僅可使用sds->card_posnum成員用于區分卡座編號
**
** 輸 出: 無
**
** 返 回 值: 0: 正確 >0: 錯誤碼, 見 sddriver.h 文件
**
** 主要工作: 1. 先給卡下電, 再給卡上電; 2. 設置訪問卡的速度小于或等于 400KHz;
**
** 3. 初始化相關硬件寄存器為適當的狀態 4. 初始化SPI控制器
********************************************************************************************************************/
INT8U SdSpiHal_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置高 */
SdSpiHal_SetMCIClock(sds, SD_RATE_SLOW); /* 設置SPI頻率小于等于400kHZ */
S0SPCR = (0x00 << 4) + (0x01 << 5); /* 設置SPI接口模式, MSTR = 1,CPOL = 1,CPHA = 0,LSBF=0 */
return SD_NO_ERR;
}
/*******************************************************************************************************************
** 函數名稱: SdSpiHal_SetMCIClock()
**
** 功能描述: 設置讀寫SD/MMC卡時鐘
**
** 輸 入: sd_struct *sds : 卡信息結構體, 該函數僅可使用sds->card_posnum成員用于區分卡座編號
** INT32U ClockRate: 要求的時鐘速度. 取值SD_RATE_SLOW 時, 設置訪問卡速度小于 400KHz
** 取值SD_RATE_NORMAL 時, 設置訪問卡速度為卡的最大速度或主控器的最大速度
** 輸 出: 無
**
** 返 回 值: 0: 正確 >0: 錯誤碼, 見 sddriver.h 文件
**
** 注 意: 本函數有責任在ClockRate取不同的值時, 計算出相應的 sds->clkval 值, 必須大于0.
**
********************************************************************************************************************/
void SdSpiHal_SetMCIClock(sd_struct *sds, INT32U ClockRate)
{
if (ClockRate == SD_RATE_SLOW)
{
S0SPCCR = 128; /* 設置SPI時鐘分頻值為128 */
sds->host_clkval = Fpclk / 128;
}
else if (ClockRate == SD_RATE_NORMAL)
{
S0SPCCR = 8; /* 設置SPI時鐘分頻值為8 */
sds->host_clkval = Fpclk / 8;
}
}
/*******************************************************************************************************************
** 函數名稱: SdSpiHal_SendByte()
**
** 功能描述: 通過SPI控制器發送一個字節到卡
**
** 輸 入: sd_struct *sds : 卡信息結構體, 該函數僅可使用sds->card_posnum成員用于區分卡座編號
** INT8U byte : 發送的字節
**
** 輸 出: 無
**
** 返 回 值: 無
********************************************************************************************************************/
void SdSpiHal_SendByte(sd_struct *sds, INT8U byte)
{
INT8U temp;
S0SPDR = byte; /* 發送數據放入SPI數據寄存器 */
while(0 == (S0SPSR & 0x80)); /* 等待SPIF置位,即等待數據發送完畢 */
/* wait for SPIF being set, that is, wait for finishing of data being send */
temp = S0SPDR;
}
/*******************************************************************************************************************
** 函數名稱: SdSpiHal_RecByte()
**
** 功能描述: 通過SPI控制器從卡接收一個字節
**
** 輸 入: sd_struct *sds : 卡信息結構體, 該函數僅可使用sds->card_posnum成員用于區分卡座編號
**
** 輸 出: 無
**
** 返 回 值: 收到的字節
********************************************************************************************************************/
INT8U SdSpiHal_RecByte(sd_struct *sds)
{
S0SPDR = 0xFF;
while(0 == (S0SPSR & 0x80)); /* 等待SPIF置位,即等待收到數據 */
/* wait for SPIF being set, that is, wait for being received data */
return(S0SPDR); /* 讀取收到的字節 read the byte received */
}
/*******************************************************************************************************************
** 函數名稱: SdSpiHal_CSAssert()
**
** 功能描述: 通過SPI的CS引腳選擇卡
**
** 輸 入: sd_struct *sds : 卡信息結構體, 該函數僅可使用sds->card_posnum成員用于區分卡座編號
**
** 輸 出: 無
**
** 返 回 值: 無
********************************************************************************************************************/
void SdSpiHal_CSAssert(sd_struct *sds)
{
SPI_CS_CLR(); /* 片選SPI從機 select the SPI slave */
}
/*******************************************************************************************************************
** 函數名稱: SdSpiHal_CSDeassert()
**
** 功能描述: 通過SPI的CS引腳不選擇卡
**
** 輸 入: sd_struct *sds : 卡信息結構體, 該函數僅可使用sds->card_posnum成員用于區分卡座編號
**
** 輸 出: 無
**
** 返 回 值: 無
********************************************************************************************************************/
void SdSpiHal_CSDeassert(sd_struct *sds)
{
SPI_CS_SET(); /* 不片選SPI從機 not select the SPI slave */
}
/*******************************************************************************************************************
** 函數名稱: SdHal_CheckCard()
**
** 功能描述: 檢測卡是否完全插入卡座中
**
** 輸 入: sd_struct *sds: 卡信息結構體, 該函數僅可使用sds->card_posnum成員用于區分卡座編號
**
** 輸 出: 無
**
** 返 回 值: 1: 卡完全插入 0: 卡沒有完全插入
********************************************************************************************************************/
INT8U SdHal_CheckCard(sd_struct *sds)
{
if (SD_INSERT_STATUS() != 0)
return 0; /* 未完全插入 not insert entirely */
else
return 1; /* 完全插入 insert entirely */
}
/*******************************************************************************************************************
** 函數名稱: SdHal_CheckCardWP()
**
** 功能描述: 檢測卡寫保護
**
** 輸 入: sd_struct *sds: 卡信息結構體, 該函數僅可使用sds->card_posnum成員用于區分卡座編號
**
** 輸 出: 無
**
** 返 回 值: 1: 卡已寫保護 0: 卡未寫保護
********************************************************************************************************************/
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 + -