mirror of
https://github.com/rvtr/twl_wrapsdk.git
synced 2025-10-31 06:11:10 -04:00
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@96 4ee2a332-4b2b-5046-8439-1ba90f034370
1189 lines
46 KiB
C
1189 lines
46 KiB
C
/*
|
||
Project: CTR SD Card driver
|
||
File: sd_card.c
|
||
|
||
2006, Research and Development Department, Nintendo.
|
||
*/
|
||
|
||
#include <twl.h>
|
||
#include "sdmc_config.h"
|
||
#include "sdif_reg.h" /* IP 対応レジスタ定義 */
|
||
#include "sdmc.h"
|
||
#include "sdif_ip.h" /* IP 対応フラグ定義 */
|
||
|
||
#if (SD_DEBUG_PRINT_ON == 1)
|
||
#if (CTR_DEF_ENVIRONMENT_DSEMU == 1)
|
||
#define PRINTDEBUG osTPrintf
|
||
#else
|
||
#include <ctr/vlink.h>
|
||
#define PRINTDEBUG vlink_dos_printf
|
||
#endif
|
||
#else
|
||
#define PRINTDEBUG( ...) ((void)0)
|
||
#endif
|
||
|
||
|
||
#define ADD_CHECK 1
|
||
|
||
/***********************************************************************
|
||
グローバル
|
||
***********************************************************************/
|
||
u16 SD_CID[8]; /* CID保存用 (Card IDentification register) : ID*/
|
||
u16 SD_CSD[8]; /* CSD保存用 (Card Specific Data register) : spec*/
|
||
u16 SD_OCR[2]; /* OCR保存用 (Operation Condition Register) : voltage and status*/
|
||
u16 SD_SCR[4]; /* SCR保存用 (Sd card Configulation Register) : bus-width, card-ver, etc*/
|
||
u16 SD_RCA; /* RCA保存用 (Relative Card Address register) : address*/
|
||
|
||
s16 SDCARD_MMCFlag; /* MMCカードフラグ */
|
||
s16 SDCARD_SDHCFlag; /* SDHCカードフラグ(ここではPhysicalLayer2.0の意) */
|
||
u16 SD_port_number; /* 現在のポート番号 */
|
||
|
||
/***********************************************************************
|
||
外部参照変数
|
||
***********************************************************************/
|
||
extern volatile u16 SDCARD_ErrStatus; /* エラーステータス */
|
||
extern volatile u32 SDCARD_Status; /* カードステータス */
|
||
//extern volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */
|
||
//extern void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */
|
||
|
||
|
||
|
||
|
||
|
||
void SD_DisableInfo( void);
|
||
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_Init
|
||
|
||
Description: reset and initialize SD card interface
|
||
SDカードIPのリセットと初期設定
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_Init(void)
|
||
{
|
||
SD_AndFPGA( SOFT_RST,(~(SOFT_RST_SDIF_RST))); /* SD I/F モジュールをリセット */
|
||
SD_OrFPGA( SOFT_RST,((SOFT_RST_SDIF_RST))); /* SD I/F モジュールをリセット復帰 */
|
||
|
||
SD_AndFPGA( SD_STOP,(~SD_STOP_STP)); /* データ転送終了クリア */
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_EnableInfo
|
||
|
||
Description: enable SD card insert and remove interrupts.
|
||
SDカードの挿入/抜取 割り込みを許可する
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_EnableInfo( void)
|
||
{
|
||
if(SD_port_number == SDCARD_PORT0)
|
||
{
|
||
SD_AndFPGA(SD_INFO1,(~(SD_INFO1_INSERT | SD_INFO1_REMOVE))); /* SD_INFO1レジスタの card inserted removedをクリア */
|
||
SD_AndFPGA(SD_INFO1_MASK,(~(SD_INFO1_MASK_INSERT | SD_INFO1_MASK_REMOVE))); /* 挿/抜 割り込み許可 */
|
||
}
|
||
else if(SD_port_number == SDCARD_PORT1)
|
||
{ /* ポート1はCD端子が繋がっていないので実質無効 */
|
||
SD_AndFPGA(EXT_CD,(~(EXT_CD_PORT1_INSERT | EXT_CD_PORT1_REMOVE))); /* EXT_CD レジスタの card inserted removedをクリア */
|
||
SD_AndFPGA(EXT_CD_MASK,(~(EXT_CD_MASK_PORT1INSERT | EXT_CD_MASK_PORT1REMOVE))); /* 挿抜 割り込み許可 */
|
||
}
|
||
}
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_DisableInfo
|
||
|
||
Description: disable SD card insert and remove interrupts.
|
||
SDカードの挿入/抜取 割り込みを禁止する
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_DisableInfo( void)
|
||
{
|
||
if(SD_port_number == SDCARD_PORT0)
|
||
{
|
||
SD_AndFPGA(SD_INFO1,(~(SD_INFO1_INSERT | SD_INFO1_REMOVE))); /* SD_INFO1レジスタの card inserted removedをクリア */
|
||
SD_OrFPGA(SD_INFO1_MASK,(SD_INFO1_MASK_INSERT | SD_INFO1_MASK_REMOVE)); /* 挿/抜 割り込み禁止 */
|
||
}
|
||
else if(SD_port_number == SDCARD_PORT1)
|
||
{ /* ポート1はCD端子が繋がっていないので実質無効 */
|
||
SD_AndFPGA(EXT_CD,(~(EXT_CD_PORT1_INSERT | EXT_CD_PORT1_REMOVE))); /* EXT_CD レジスタの card inserted removedをクリア */
|
||
SD_OrFPGA(EXT_CD_MASK,(EXT_CD_MASK_PORT1INSERT | EXT_CD_MASK_PORT1REMOVE)); /* 挿抜 割り込み禁止 */
|
||
}
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_Command
|
||
|
||
Description: send command that the card will response only.
|
||
コマンドを送出する(レスポンスが返ってくるだけのコマンド用)
|
||
|
||
Arguments: ucCommand : command number
|
||
|
||
Returns: 0 : success
|
||
>0 : error
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_Command(u16 ucCommand)
|
||
{
|
||
SD_AndFPGA(SD_INFO2,(~SD_INFO2_ERR_ALLCLR)); /* SD Card I/F の 全エラーをクリア */
|
||
SD_AndFPGA(SD_INFO1,(~SD_INFO1_RES_END)); /* SD_INFO1レジスタの Response end クリア */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み許可 */
|
||
|
||
SD_SetFPGA(SD_CMD,(ucCommand)); /* コマンド発行 */
|
||
|
||
while(!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_RES_END)){ /* Response end 待ち */
|
||
if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトチェック */
|
||
break;
|
||
}
|
||
}
|
||
|
||
SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の全エラー割込み禁止 */
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_AppCommand
|
||
|
||
Description: send apprication command.
|
||
アプリケーションコマンド(CMD55)を送出する
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
>0 : error
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_AppCommand(void)
|
||
{
|
||
PRINTDEBUG( " CMD55 (APP_CMD)\n");
|
||
|
||
/* argumentをセット */
|
||
SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) = stuff bits */
|
||
SD_SetFPGA(SD_ARG1,(SD_RCA)); /* Argument(31:16) = RCA */
|
||
|
||
SD_Command(SD_CMD_CMD | APP_CMD); /* CMD55発行、レスポンス(R1)待ち */
|
||
|
||
#if ADD_CHECK
|
||
/*SD_CheckStatusを行うと、直前にCMD8を発行していた場合、SDHC以外はCardStatusの
|
||
IllegalCommandエラーフラグが立ってしまうので、ここで引っかかることになる
|
||
(このフラグがクリアされるのは1コマンドぶん遅れるため)
|
||
SD Physical Layer 仕様書の Card Status参照*/
|
||
// SD_CheckStatus(FALSE); /* コマンドレスポンス(R1) の Card Status チェック */
|
||
#endif
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_AppOpCond
|
||
|
||
Description: get operating condition register data of SD card.
|
||
SDカードのACMD41を発行してOCRを取得する
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_AppOpCond(void)
|
||
{
|
||
SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウト以外のエラーをクリア */
|
||
|
||
while(!SDCARD_ErrStatus){ /* エラーが発生しない間は繰り返し */
|
||
/* Argument(31:0) = OCR without busy (0x00100000 = 3.2-3.3V) */
|
||
/*ホスト側で電圧を選択できる場合などは、初回にSD_ARG1を0にすることにより
|
||
カードが対応している電圧を問い合わせることができる。CTRは電圧3.3V決め打ち
|
||
なので問い合わせせず、いきなり3.3V対応をカードに要求する。対応できない
|
||
カードは Inactive Mode に移行する。*/
|
||
SD_SetFPGA(SD_ARG0,(0x0000));
|
||
if( SDCARD_SDHCFlag) {
|
||
SD_SetFPGA(SD_ARG1,(0x4010));
|
||
}else{
|
||
SD_SetFPGA(SD_ARG1,(0x0010));
|
||
}
|
||
|
||
PRINTDEBUG( " ACMD41 (SD_SEND_OP_COND)\n");
|
||
SD_Command(SD_CMD_ACMD | SD_APP_OP_COND); /* ACMD41発行、レスポンス(R3)待ち */
|
||
|
||
if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?)*/
|
||
SD_GetFPGA(SD_OCR[0],SD_RSP0); /* レスポンス(R3)からOCR取得 */
|
||
SD_GetFPGA(SD_OCR[1],SD_RSP1); /* レスポンス(R3)からOCR取得 */
|
||
if(SD_RSP1 & RSP_R3_OCR31){ /* OCR(レジスタ)の31bit目チェック(busy?) */
|
||
break;
|
||
}
|
||
}
|
||
SD_AppCommand(); /* 決定済みのRCAを設定しCMD55発行 */
|
||
}
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SendOpCond
|
||
|
||
Description: send CMD1 without busy for MMC
|
||
MMC の CMD1を発行する(SDのACMD41に位置するコマンド)
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SendOpCond(void)
|
||
{
|
||
PRINTDEBUG( " CMD1 (SEND_OP_COND)\n");
|
||
|
||
SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウトエラーをクリア */
|
||
|
||
while(!SDCARD_ErrStatus){ /* エラーが発生しない間は繰り返し */
|
||
SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) for MMC (None for SD) */
|
||
SD_SetFPGA(SD_ARG1,(0x0010)); /* Argument(31:16) for MMC (None for SD) */
|
||
SD_Command(SD_CMD_CMD | SEND_OP_COND); /* CMD1発行、レスポンス(R1)待ち */
|
||
if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */
|
||
SD_GetFPGA(SD_OCR[0],SD_RSP0);
|
||
SD_GetFPGA(SD_OCR[1],SD_RSP1);
|
||
if(SD_RSP1 & RSP_R3_OCR31){ /* OCR(レジスタ)の31bit目チェック(busy?) */
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SendIfCond
|
||
|
||
Description: send CMD8
|
||
CMD8を発行する(Physical Layer 2.00で追加されたコマンド)
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SendIfCond(void)
|
||
{
|
||
PRINTDEBUG( " CMD8 (SEND_IF_COND)\n");
|
||
|
||
SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウトエラーをクリア */
|
||
|
||
/* (31:12) Reserved bits, (11:8) supply voltage(VHS), (7:0) check pattern */
|
||
SD_SetFPGA(SD_ARG0,(0x01AA)); /* Argument */
|
||
SD_SetFPGA(SD_ARG1,(0x0000)); /* Argument */
|
||
|
||
SD_Command(SD_CMD_CMD | SEND_IF_COND_EXT); /* CMD8発行、レスポンス(R7)待ち */
|
||
|
||
if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */
|
||
SDCARD_SDHCFlag = TRUE; /* SDHC */
|
||
// SD_GetFPGA(SD_R7[0],SD_RSP0);
|
||
// SD_GetFPGA(SD_R7[1],SD_RSP1);
|
||
}else{
|
||
SDCARD_SDHCFlag = FALSE;
|
||
}
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SendRelativeAddr
|
||
|
||
Description: send relative addr
|
||
CMD3を発行し、SDカードの場合はレスポンスのRCAを取得する
|
||
(RCAは他のコマンド発行時にArgumentとして必要)
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SendRelativeAddr(void)
|
||
{
|
||
PRINTDEBUG( " CMD3 (SEND_RELATIVE_ADDR)\n");
|
||
|
||
if(SDCARD_MMCFlag){ /* MMCカードフラグ ON ? */
|
||
SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) */
|
||
SD_SetFPGA(SD_ARG1,(0x0001)); /* Argument(31:16) = 0x0001 (松下drvはなぜか0x0100にしていた) */
|
||
} /* SDカードのときはArgument(31:0) = stuff bits */
|
||
|
||
SD_Command(SD_CMD_CMD | SEND_RELATIVE_ADDR); /* CMD3発行、レスポンス(R6)待ち */
|
||
|
||
if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */
|
||
if(SDCARD_MMCFlag){ /* MMCカードフラグ ON ? */
|
||
SD_RCA = 0x0001; /* RCA <- 1 (松下drvはなぜか0x0100にしていた) */
|
||
}else{
|
||
SD_GetFPGA(SD_RCA,SD_RSP1); /* レスポンスレジスタからRCAを取得 */
|
||
}
|
||
}
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SelectCard
|
||
|
||
Description: toggle card between the stand-by and transfer states.
|
||
CMD7を発行してスタンバイモードと転送モードを切り替える
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SelectCard(void)
|
||
{
|
||
PRINTDEBUG( " CMD7 (SELECT#/DESELECT_CARD)\n");
|
||
|
||
SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) = stuff bits*/
|
||
SD_SetFPGA(SD_ARG1,(SD_RCA)); /* Argument(31:16) = RCA */
|
||
|
||
SD_Command(SD_CMD_CMD | SELECT_CARD); /* CMD7発行、レスポンス(R1b)待ち */
|
||
|
||
#if ADD_CHECK
|
||
SD_CheckStatus(FALSE); /* コマンドレスポンス(R1) の Card Status チェック */
|
||
#endif
|
||
|
||
return SDCARD_ErrStatus;
|
||
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SetBlockLength
|
||
|
||
Description: set of block length.
|
||
SDカードのブロックレングスを設定する。
|
||
注意:multiple read のときに SD_SIZEレジスタに512以外の値を
|
||
設定すると正しく動作しない(IP reg spec資料より)。
|
||
|
||
Arguments: ulBlockLength : bytes of a block ( must be multiplier of 2)
|
||
(memo : the default block length is as specified in the CSD.)
|
||
1ブロックの長さ:2の乗数を指定すること
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SetBlockLength(u32 ulBlockLength)
|
||
{
|
||
u16 usValue;
|
||
|
||
PRINTDEBUG( " CMD16 (SET_BLOCKLEN)\n");
|
||
|
||
/*------- IPの transfer length を設定 -------*/
|
||
if(ulBlockLength == 512){
|
||
SD_SetFPGA(SD_SIZE,(SD_SIZE_DATA_LENGTH_512B)); /* SDカードデータ転送サイズ 512Bytes 設定 */
|
||
}else{
|
||
usValue = (u16)ulBlockLength; /* 16bitに変換 */
|
||
SD_SetFPGA(SD_SIZE,(usValue)); /* IPにSDカードデータ転送サイズを設定 */
|
||
}/*------------------------------------------*/
|
||
|
||
/*------- カードの設定 -------*/
|
||
/* argument(31:0) = block length */
|
||
SD_SetFPGA(SD_ARG0,(((LELONG *)&ulBlockLength)->dt2word.low));
|
||
SD_SetFPGA(SD_ARG1,(((LELONG *)&ulBlockLength)->dt2word.high));
|
||
|
||
SD_Command(SD_CMD_CMD | SET_BLOCKLEN); /* CMD16発行、レスポンス(R1)待ち */
|
||
#if ADD_CHECK
|
||
SD_CheckStatus(FALSE); /* コマンドレスポンス(R1) の Card Status チェック */
|
||
#endif
|
||
/*----------------------------*/
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SendCID
|
||
|
||
Description: get card identification data (128bits).
|
||
SDカードのCID値を取得する
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SendCID(void)
|
||
{
|
||
PRINTDEBUG( " CMD2 (ALL_SEND_CID)\n");
|
||
/* Argument(31:0) = stuff bits */
|
||
SD_Command(SD_CMD_CMD | ALL_SEND_CID); /* CMD2発行、レスポンス(R2)待ち */
|
||
|
||
if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */
|
||
SD_GetFPGA(SD_CID[0],SD_RSP0);
|
||
SD_GetFPGA(SD_CID[1],SD_RSP1);
|
||
SD_GetFPGA(SD_CID[2],SD_RSP2);
|
||
SD_GetFPGA(SD_CID[3],SD_RSP3);
|
||
SD_GetFPGA(SD_CID[4],SD_RSP4);
|
||
SD_GetFPGA(SD_CID[5],SD_RSP5);
|
||
SD_GetFPGA(SD_CID[6],SD_RSP6);
|
||
SD_GetFPGA(SD_CID[7],SD_RSP7);
|
||
}
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SendCSD
|
||
|
||
Description: get card specific data
|
||
SDカードのCSD値を取得する
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SendCSD(void)
|
||
{
|
||
PRINTDEBUG( " CMD9 (SEND_CSD)\n");
|
||
|
||
SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) = stuff bits */
|
||
SD_SetFPGA(SD_ARG1,(SD_RCA)); /* Argument(31:16) = RCA */
|
||
|
||
SD_Command(SD_CMD_CMD | SEND_CSD); /* CMD9発行、レスポンス(R2)待ち */
|
||
|
||
if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */
|
||
SD_GetFPGA(SD_CSD[0],SD_RSP0);
|
||
SD_GetFPGA(SD_CSD[1],SD_RSP1);
|
||
SD_GetFPGA(SD_CSD[2],SD_RSP2);
|
||
SD_GetFPGA(SD_CSD[3],SD_RSP3);
|
||
SD_GetFPGA(SD_CSD[4],SD_RSP4);
|
||
SD_GetFPGA(SD_CSD[5],SD_RSP5);
|
||
SD_GetFPGA(SD_CSD[6],SD_RSP6);
|
||
SD_GetFPGA(SD_CSD[7],SD_RSP7);
|
||
}
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SendStatus
|
||
|
||
Description: send status read command (compatible to the MMC protocol).
|
||
マルチメディアカード互換方式でのstatus取得コマンド発行
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SendStatus(void)
|
||
{
|
||
PRINTDEBUG( " CMD13 (Send STATUS)\n");
|
||
|
||
SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:0) = stuff bits */
|
||
SD_SetFPGA(SD_ARG1,(SD_RCA)); /* Argument(31:16) = RCA */
|
||
|
||
/* カード排出の重複を防ぐため */
|
||
SD_AndFPGA(SD_INFO2,(~SD_INFO2_ERR_ALLCLR)); /* SD Card I/F の 全てのエラーをクリア */
|
||
SD_AndFPGA(SD_INFO1,(~SD_INFO1_RES_END)); /* SD_INFO1レジスタの Response end クリア */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み許可 */
|
||
|
||
SD_SetFPGA(SD_CMD,(SD_CMD_CMD | SD_SEND_STATUS)); /* CMD13発行 */
|
||
|
||
while(!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_RES_END)){ /* Response end (R1)待ち */
|
||
if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){
|
||
break;
|
||
}
|
||
}
|
||
|
||
SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み禁止 */
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SendSCR
|
||
|
||
Description: get condition data.
|
||
SDカード内のSCRレジスタ値取得コマンド発行。この後カードは
|
||
DATライン経由で1ブロック(8Bytesに設定しておくこと)送信してくる。
|
||
MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの
|
||
レジスタは、MSBから先に送られてくることに注意。
|
||
(Physical Layer Specification 2.00 p12-13参照)
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SendSCR(void)
|
||
{
|
||
PRINTDEBUG( " ACMD51 (Send SCR)\n");
|
||
/* Argument(31:0) = stuff bits */
|
||
#if ADD_CHECK
|
||
SD_TransReadyFPGA(); /* 関連レジスタ初期化 */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BRE)); /* SDカードからのデータ読出し要求割込み許可*/
|
||
|
||
SD_TransCommand((SD_CMD_ACMD | SEND_SCR)); /* SCR取得コマンド発行、レスポンス(R1)待ち */
|
||
#endif
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SDStatus
|
||
|
||
Description: send status read command (for SD card only).
|
||
SDカード専用方式でのstatus取得コマンド発行。この後カードは
|
||
DATライン経由で1ブロック(64Bytesに設定しておくこと)送信してくる。
|
||
MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの
|
||
レジスタは、MSBから先に送られてくることに注意。
|
||
(Physical Layer Specification 2.00 p12-13参照)
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SDStatus(void)
|
||
{
|
||
PRINTDEBUG( " ACMD13 (SD_SD STATUS)\n");
|
||
/* Argument(31:0) = stuff bits */
|
||
SD_TransReadyFPGA(); /* 関連レジスタ初期化 */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BRE)); /* SDカードからのデータ読出し要求割込み許可*/
|
||
|
||
SD_TransCommand((SD_CMD_ACMD | SD_STATUS)); /* ACMD13 Send the SD_CARD status コマンド発行、レスポンス(R1)待ち */
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_MultiReadBlock
|
||
|
||
Description: send multiple block read command.
|
||
マルチブロックリードコマンド発行。この後カードは
|
||
DATライン経由でデータを送信してくる。
|
||
|
||
Arguments: ulOffset : offset address to read(BYTE).
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_MultiReadBlock(u32 ulOffset)
|
||
{
|
||
PRINTDEBUG( " CMD18 (READ_MULTIPLE_BLOCK)\n");
|
||
|
||
SD_TransReadyFPGA(); /* INFOレジスタ初期化 */
|
||
if( !SDCARD_UseFifoFlag) { /* FIFOを使わないとき */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BRE)); /* SDカードからのデータ読出し要求割込み許可*/
|
||
}
|
||
|
||
/* 読み込み開始アドレス(オフセット)設定 */
|
||
SD_SetFPGA(SD_ARG0,(((LELONG *)&ulOffset)->dt2word.low));
|
||
SD_SetFPGA(SD_ARG1,(((LELONG *)&ulOffset)->dt2word.high));
|
||
|
||
SD_TransCommand((READ_MULTIPLE_BLOCK)); /* CMD18(マルチセクタリードコマンド)発行、レスポンス(R1)待ち */
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_ClockDivSet
|
||
|
||
Description: set clock speed into the SD card.
|
||
(notice : clock into IP is 33.51MHz.)
|
||
(memo : default clock is 262KHz.)
|
||
SDカードへのクロック速度を設定する。CTRからIMCLK端子でIPに供給
|
||
される基本クロックは33.51MHz。
|
||
起動直後のデフォルトでは128分周(262KHz)が設定されている。
|
||
|
||
Arguments: CSD responce include "TRAN_SPEED".
|
||
予めCSDをSDカードから読み出しておいた、TRAN_SPEEDが入っている
|
||
部分のCSD(CSD[5])。SDカード側で対応可能な周波数を参照するため。
|
||
|
||
Returns: 0 : success
|
||
> 0 : error
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_ClockDivSet(u16 usTranSpeed)
|
||
{
|
||
u16 usTranTime;
|
||
|
||
//CTRでは、IMCLKに入力されるクロックは 33.51Mhz
|
||
//SD_CLK_CTRL の default値は 0x0020( 128分周 = 262kHz)
|
||
/*------*/
|
||
usTranTime = (u16)((usTranSpeed >> 11) & 0x000F); /* CSD[103:96] の time value(=4bit) 取得 */
|
||
|
||
usTranSpeed &= CSD_TRANSFER_RATE; /* CSD[103:96] の transfer rate unit を取得 */
|
||
usTranSpeed = (u16)(usTranSpeed >> 8); /* transfer rate unit を下位8ビットに設定する */
|
||
/*------*/
|
||
|
||
|
||
switch( usTranSpeed) {
|
||
/*--- 100kbit/s(one dat line) = 100KHz, の倍数のとき ---*/
|
||
case CSD_TRAN_SPEED_100K:
|
||
if(usTranTime > 0x000C){ /* time value が 5.5 より大きい? */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_64)); /* 523KHz */
|
||
}
|
||
else{
|
||
if(usTranTime > 0x0006){ /* time value が 2.5 より大きい? */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_128)); /* 262KHz */
|
||
}else{
|
||
if( usTranTime == 1) { /* time value が 1.0 ? */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_512)); /* 65KHz */
|
||
}else{ /* time value が 1.2~2.5 のとき */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_256)); /* 131KHz */
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
/*--- 1Mbit/s(one dat line) = 1MHz, の倍数のとき ---*/
|
||
case CSD_TRAN_SPEED_1M:
|
||
if(usTranTime == 0x0001){ /* time value が 1.0 ? */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_64)); /* 523KHz */
|
||
}
|
||
else{
|
||
if(usTranTime <= 0x0005){ /* time value が 2.0 以下? */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_32)); /* 1.05MHz */
|
||
}
|
||
else{
|
||
if(usTranTime <= 0x0009){ /* time value が 4.0 以下? */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_16)); /* 2.095MHz */
|
||
}else{ /* time value が 4.5 以上のとき */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_8)); /* 4.18MHz */
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
/*--- 10Mbit/s(one dat line) = 10MHz, の倍数のとき ---*/
|
||
case CSD_TRAN_SPEED_10M:
|
||
if(usTranTime > 0x0004){ /* time value が 1.5 より大きい? */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_2)); /* 16.76MHz */
|
||
}else{ /* time value が 1.5 以下のとき */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_4)); /* 8.38MHz */
|
||
}
|
||
break;
|
||
/*--- 100Mbit/s(one dat line) = 100MHz, の倍数のとき ---*/
|
||
case CSD_TRAN_SPEED_100M: /* time value がどんな値であっても */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_2)); /* 16.76MHz */
|
||
break;
|
||
default:
|
||
if( usTranSpeed != 7) { /* reserved値(=7)以外か? */
|
||
SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_2)); /* 16.76MHz */
|
||
} /* (松下drvでは、4以上なら288KHzにしている) */
|
||
break; /* transfer rate unit が 7 のときは何もしない */
|
||
}
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_EnableClock
|
||
|
||
Description: enable clock
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_EnableClock( void)
|
||
{
|
||
SD_OrFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_SDCLKEN));
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_DisableClock
|
||
|
||
Description: disable clock (for power save).
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_DisableClock( void)
|
||
{
|
||
SD_AndFPGA(SD_CLK_CTRL,(~SD_CLK_CTRL_SDCLKEN));
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SelectBitWidth
|
||
|
||
Description: set bus width for SD Card ( Not for MMC Card).
|
||
(The allowed data bus widths are given in SCR register.)
|
||
SDカードのDATラインバス幅を1bitまたは4bitに設定する。
|
||
SDカードが4bitに対応していないか、MMCカードの場合はバス幅を4bitに
|
||
設定することはできない。SDカードの許容するバス幅は、予め取得済みの
|
||
SCRレジスタによって参照している。
|
||
|
||
Arguments: b4bit : TRUE = 4bit, FALSE = 1bit
|
||
|
||
Returns: 0 : success
|
||
> 0 : error
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SelectBitWidth(s16 b4bit)
|
||
{
|
||
/*--- カードの仕様(SCR)を参照 ---*/
|
||
#if ADD_CHECK
|
||
if( b4bit){ /* SCRレジスタがリード済であること! */
|
||
if( !(SD_SCR[0] & SCR_DAT_BUS_WIDTH_4BIT)) { /* カードが4bit幅に対応していないか? */
|
||
b4bit = FALSE; /* 対応していない場合は1bit幅を指定しておく */
|
||
}
|
||
}/*------------------------------*/
|
||
#endif
|
||
/*--- 4bit(TRUE) 指定のとき ---*/
|
||
if(b4bit){
|
||
if(!SDCARD_MMCFlag){ /* MMCカードフラグ OFF?(ONなら何もしない) */
|
||
if(SD_AppCommand()){ /* RCA設定後 CMD55発行 */
|
||
return SDCARD_ErrStatus; /* CMD55が正常終了しなかったらエラー終了 */
|
||
}
|
||
SD_SetFPGA(SD_ARG0,(0x0002)); /* Argument(1:0) = (10) to 4bit,(00) to 1bit */
|
||
SD_SetFPGA(SD_ARG1,(0x0000)); /* Argument(31:2) = stuff bits */
|
||
PRINTDEBUG( " ACMD6 (SET_BUS_WIDTH:4bit)\n");
|
||
SD_Command(SD_CMD_ACMD | SET_BUS_WIDTH); /* ACMD6(ビット幅選択コマンド)発行、レスポンス(R1)待ち */
|
||
#if ADD_CHECK
|
||
SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */
|
||
#endif
|
||
if(!SDCARD_ErrStatus){ /* エラーなし? */
|
||
SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */
|
||
}
|
||
}
|
||
}/*--- 1bit(FALSE) 指定のとき ---*/
|
||
else{
|
||
if(!SDCARD_MMCFlag){ /* MMCカードフラグ OFF?(ONなら何もしない) */
|
||
if(SD_AppCommand()){ /* RCA設定後 CMD55発行処理 */
|
||
return SDCARD_ErrStatus; /* CMD55が正常終了しなかったらエラー終了 */
|
||
}
|
||
SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(1:0) = bus width : 1bit */
|
||
SD_SetFPGA(SD_ARG1,(0x0000)); /* Argument(31:2) = stuff bits */
|
||
PRINTDEBUG( " ACMD6 (SET_BUS_WIDTH:1bit)\n");
|
||
SD_Command(SD_CMD_ACMD | SET_BUS_WIDTH); /* ACMD6(ビット幅選択コマンド)発行、レスポンス(R1)待ち */
|
||
#if ADD_CHECK
|
||
SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */
|
||
#endif
|
||
}
|
||
if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー無し?) */
|
||
SD_OrFPGA(SD_OPTION,(SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(1bit幅) */
|
||
}
|
||
}/*------------------------------*/
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: MMCP_WriteBusWidth
|
||
|
||
Description: set bus width for SD Card ( Not for MMC Card).
|
||
(The allowed data bus widths are given in SCR register.)
|
||
MMCplusカードのDATラインバス幅を1bitまたは4bitに設定する。
|
||
SDまたはMMCカードの場合はバス幅を4bitに設定することはできない。
|
||
|
||
Arguments: b4bit : TRUE = 4bit, FALSE = 1bit
|
||
|
||
Returns: 0 : success
|
||
> 0 : error
|
||
*---------------------------------------------------------------------------*/
|
||
u16 MMCP_WriteBusWidth(s16 b4bit)
|
||
{
|
||
if( !SDCARD_MMCFlag) {
|
||
return 1;
|
||
}
|
||
|
||
/* 書き込み開始オフセット設定 */
|
||
if( b4bit) {
|
||
SD_SetFPGA(SD_ARG0,(0x0100)); /* Argument(15:8)=(0x1) to 4bit,(0x0) to 1bit */
|
||
}else{
|
||
SD_SetFPGA(SD_ARG0,(0x0000)); /* Argument(15:8)=(0x1) to 4bit,(0x0) to 1bit */
|
||
}
|
||
SD_SetFPGA(SD_ARG1,(0x03B7)); /* Argument(25:24)=(0x3)Write, (23:16)=(183)Index */
|
||
|
||
/* CMD6(ビット幅選択コマンド)発行、レスポンス(R1)待ち */
|
||
SD_Command(SD_CMD_CMD | EXT_CSD_ACCESS);
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: MMCP_BusTest
|
||
|
||
Description: バスのテストを行う。
|
||
この後カードにDATライン経由でデータを送信する必要がある。
|
||
|
||
Arguments: readflag : リード時TRUE, ライト時FALSE
|
||
|
||
Returns: 0 : success
|
||
> 0 : error
|
||
*---------------------------------------------------------------------------*/
|
||
u16 MMCP_BusTest( BOOL readflag)
|
||
{
|
||
/**/
|
||
SD_TransReadyFPGA(); /* INFOレジスタ初期化 */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BWE)); /* SDカードからのデータ書込み要求割込み許可 */
|
||
|
||
/**/
|
||
SD_SetFPGA( SD_ARG0, 0);
|
||
SD_SetFPGA( SD_ARG1, 0);
|
||
|
||
if( readflag) {
|
||
SD_TransCommand( 14);
|
||
}else{
|
||
SD_TransCommand( 19);
|
||
}
|
||
|
||
return( SDCARD_ErrStatus);
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_FPGA_irq
|
||
|
||
Description: handler of data transfer request interrupt from card,
|
||
check and clear interrupt register of IP.
|
||
カードからの転送要求(BREまたはBWE)割り込み発生時に
|
||
どちらかを調べて返し、INFO2の当該割り込み要求フラグをクリアする。
|
||
|
||
Arguments: None
|
||
|
||
Returns: TRUE : BRE割り込み発生
|
||
FALSE : BWE割り込み発生
|
||
*---------------------------------------------------------------------------*/
|
||
s16 SD_FPGA_irq(void)
|
||
{
|
||
/*--- FIFOを使うとき ---*/
|
||
if( SDCARD_UseFifoFlag) {
|
||
if( SD_CheckFPGAReg( *SDIF_CNT_L, (u16)SDIF_CNT_FFIE)) { /* FULL割り込み許可のとき */
|
||
return TRUE;
|
||
}else{
|
||
if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BWE)){ /* SDカードからのデータ書込み要求あり? */
|
||
SD_AndFPGA(SD_INFO2,(~SD_INFO2_BWE)); /* SD用バッファ制御 Write Enable リセット*/
|
||
}
|
||
return FALSE;
|
||
}
|
||
}else{ /*--- FIFOを使わないとき ---*/
|
||
if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BRE)){ /* SDカードからのデータ読出し要求あり? */
|
||
SD_AndFPGA(SD_INFO2,(~SD_INFO2_BRE)); /* SD用バッファ制御 Read Enable リセット*/
|
||
return TRUE;
|
||
}
|
||
if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BWE)){ /* SDカードからのデータ書込み要求あり? */
|
||
SD_AndFPGA(SD_INFO2,(~SD_INFO2_BWE)); /* SD用バッファ制御 Write Enable リセット*/
|
||
return FALSE;
|
||
}
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_StopTransmission
|
||
|
||
Description: manual send CMD12 to terminate translate.
|
||
手動でCMD12を発行し、転送終了をFPGAに通知する
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_StopTransmission(void)
|
||
{
|
||
SD_OrFPGA(SD_STOP,(SD_STOP_STP)); /* データ転送終了設定 */
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_TransEndFPGA
|
||
|
||
Description: clear the transfer interrupt.
|
||
カード転送終了時に転送関連の割り込みを禁止に戻しておく
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_TransEndFPGA(void)
|
||
{
|
||
SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み禁止 */
|
||
SD_OrFPGA(SD_INFO1_MASK,(SD_INFO1_MASK_ALL_END)); /* R/W アクセス終了割込み禁止 */
|
||
|
||
if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BRE)){ /* SDカードからのデータ読込み要求割込み許可か? */
|
||
SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_BRE)); /* SDカードからのデータ読込み要求割込み禁止 */
|
||
}
|
||
if(!SD_CheckFPGAReg(SD_INFO2_MASK,SD_INFO2_MASK_BWE)){ /* SDカードからのデータ書込み要求割込み許可か? */
|
||
SD_OrFPGA(SD_INFO2_MASK,(SD_INFO2_MASK_BWE)); /* SDカードからのデータ書込み要求割込み禁止 */
|
||
}
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_CheckStatus
|
||
|
||
Description: check the card status in the R1.
|
||
R1レスポンスのカードステータスをチェックする
|
||
|
||
Arguments: bRead : 読み込み処理時 = TRUE
|
||
|
||
Returns: 0 : success
|
||
>0 : error
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_CheckStatus(BOOL bRead)
|
||
{
|
||
/* コマンドレスポンス(R1)の[39:8] から Card status を取得 */
|
||
SD_GetFPGA((((LELONG *)&SDCARD_Status)->dt2word.low),SD_RSP0);
|
||
SD_GetFPGA((((LELONG *)&SDCARD_Status)->dt2word.high),SD_RSP1);
|
||
|
||
/*--- 松下サンプルドライバでやっている処理 ---*/
|
||
if(bRead){ /* リード時か? */
|
||
if(!(SDCARD_ErrStatus & SDMC_ERR_TIMEOUT)){ /* タイムアウト発生していないか? */
|
||
SDCARD_Status &= ~SDCARD_STATUS_OUT_OF_RANGE; /* OUT_OF_RANGEフラグを落とす */
|
||
}
|
||
}/*-------------------------------------------*/
|
||
|
||
PRINTDEBUG( " SD_CheckStatus ======== 0x%x\n", SDCARD_Status);
|
||
|
||
if(SDCARD_Status & RSP_R1_STATUS_ERR){ /* コマンドレスポンス(R1)のカードステータスがエラーか確認 */
|
||
SD_SetErr(SDMC_ERR_R1_STATUS); /* コマンドレスポンス(R1)のカードステータス エラー */
|
||
}
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SwapByte
|
||
|
||
Description: swap bytes in a 16bit data.
|
||
16bitデータの上位と下位を入れ換える
|
||
|
||
Arguments: data : 16bit data
|
||
|
||
Returns: swapped data
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SwapByte(u16 *data)
|
||
{
|
||
u16 usDATA;
|
||
|
||
usDATA = *data;
|
||
usDATA = (u16)(((usDATA & 0x00FF) << 8) | ((usDATA & 0xFF00) >> 8));
|
||
|
||
return usDATA;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_EnableSeccnt
|
||
|
||
Description: enable SD_SECCNT register.
|
||
SD_SECCNT を有効化して値をセットする。
|
||
|
||
Arguments: ulSDCARD_SectorCount : セクタカウント値(1セクタ=512byte)
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_EnableSeccnt( u32 ulSDCARD_SectorCount)
|
||
{
|
||
u16 usSector;
|
||
|
||
usSector = (u16)ulSDCARD_SectorCount;
|
||
SD_OrFPGA(SD_STOP,SD_STOP_SEC_ENABLE); /* SD_SECCNTレジスタを有効にする */
|
||
SD_SetFPGA(SD_SECCNT,usSector); /* SD_SECCNTレジスタに転送セクタカウントを設定 */
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_DisableSeccnt<現在は未使用関数>
|
||
|
||
Description: disable SD_SECCNT register.
|
||
SD_SECCNT を無効化する。
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_DisableSeccnt( void)
|
||
{
|
||
u16 i;
|
||
|
||
/*--- 松下ドライバでやっていること ---*/
|
||
for ( i=0; i<50000; i++) /* カウント値50000では足りないことあり */
|
||
{ /* SD_INFO1レジスタの R/W access all end 待ち */
|
||
if(SD_CheckFPGAReg(SD_INFO1,SD_INFO1_ALL_END)) {
|
||
break;
|
||
}
|
||
}/*-----------------------------------*/
|
||
SD_AndFPGA(SD_STOP,(~SD_STOP_SEC_ENABLE)); /* SD_SECCNTレジスタを無効にする */
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SetErr
|
||
|
||
Description: set error flag
|
||
指定のエラーフラグをセットする
|
||
|
||
Arguments: Error : error flag to set
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_SetErr(u16 Error)
|
||
{
|
||
OSIntrMode irq_core_flag;
|
||
|
||
#if (TARGET_OS_CTR == 1)
|
||
irq_core_flag = osDisableInterrupts(); /* 割込み禁止 */
|
||
SDCARD_ErrStatus |= Error; /* エラーステータスを設定 */
|
||
osRestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */
|
||
#else
|
||
irq_core_flag = OS_DisableInterrupts();
|
||
SDCARD_ErrStatus |= Error; /* エラーステータスを設定 */
|
||
OS_RestoreInterrupts( irq_core_flag);
|
||
#endif
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_ClrErr
|
||
|
||
Description: clear error flag
|
||
指定のエラーフラグをクリアする
|
||
|
||
Arguments: Error : error flag to clear
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_ClrErr(u16 Error)
|
||
{
|
||
OSIntrMode irq_core_flag;
|
||
|
||
#if (TARGET_OS_CTR == 1)
|
||
irq_core_flag = osDisableInterrupts(); /* 割込み禁止 */
|
||
SDCARD_ErrStatus &= ~(Error); /* エラーステータスをクリア */
|
||
osRestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */
|
||
#else
|
||
irq_core_flag = OS_DisableInterrupts(); /* 割込み禁止 */
|
||
SDCARD_ErrStatus &= ~(Error); /* エラーステータスをクリア */
|
||
OS_RestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */
|
||
#endif
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_TransReadyFPGA
|
||
|
||
Description: setup for the command that the card will response and request data transfer.
|
||
DATラインでのデータ転送が発生するコマンド発行前の転送準備
|
||
(BRE, BWE割り込みの許可は別途行うこと)
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
void SD_TransReadyFPGA(void)
|
||
{
|
||
/* 関連レジスタ初期化 */
|
||
SD_AndFPGA(SD_INFO2,(~SD_INFO2_ERR_ALLCLR)); /* SD Card I/F の 全てのエラーをクリア */
|
||
SD_AndFPGA(SD_INFO1,(~(SD_INFO1_RES_END | SD_INFO1_ALL_END))); /* SD_INFO1レジスタの Response end と access all end クリア */
|
||
SD_AndFPGA(SD_INFO2,(~SD_INFO2_BRE)); /* SD用バッファ制御 Read Enable クリア*/
|
||
SD_AndFPGA(SD_INFO2,(~SD_INFO2_BWE)); /* SD用バッファ制御 Write Enable クリア*/
|
||
SD_AndFPGA(SD_STOP,(~SD_STOP_STP)); /* データ転送終了クリア */
|
||
|
||
/* 割り込み関連許可 */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_ALLERRMASK)); /* SD Card I/F の 全エラー割込み許可 */
|
||
SD_AndFPGA(SD_INFO1_MASK,(~SD_INFO1_MASK_ALL_END)); /* R/W access all end 割込み許可(Responseはポーリングで見るため許可しない) */
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_TransCommand
|
||
|
||
Description: send command that the card will response and request data transfer.
|
||
コマンドを送出する(DATラインでのデータ転送が発生するコマンド用)
|
||
|
||
Arguments: ucCommand : command number
|
||
|
||
Returns: 0 : success
|
||
>0 : error
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_TransCommand(u16 ucCommand)
|
||
{
|
||
SD_SetFPGA(SD_CMD,(ucCommand)); /* コマンド発行 */
|
||
|
||
while(!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_RES_END)){ /* Response end 待ち */
|
||
if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){
|
||
break;
|
||
}
|
||
}
|
||
SD_CheckStatus(FALSE); /* R1レスポンスのcard statusチェック*/
|
||
|
||
if(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS){
|
||
SD_StopTransmission(); /* カード転送終了をFPGAに通知 */
|
||
}
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_CheckFPGAReg
|
||
|
||
Description: check register bits.
|
||
レジスタの状態をチェックする
|
||
|
||
Arguments: reg : 16bit register data
|
||
value : mask data
|
||
|
||
Returns: TRUE : some of mask data bits are 1 on the register.
|
||
FALSE : no mask data bits is 1 on the register.
|
||
*---------------------------------------------------------------------------*/
|
||
BOOL SD_CheckFPGAReg(u16 reg,u16 value)
|
||
{
|
||
if( reg & value) {
|
||
return TRUE;
|
||
}else{
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_SendNumWRSectors
|
||
|
||
Description: send "number of well written blocks" command (for SD card only).
|
||
SDカード専用方式でのライト済みセクタ数取得コマンド発行。この後カードは
|
||
DATライン経由で1ブロック(4Bytesに設定しておくこと)送信してくる。
|
||
MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの
|
||
レジスタは、MSBから先に送られてくることに注意。
|
||
(Physical Layer Specification 2.00 p12-13参照)
|
||
|
||
Arguments: None
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_SendNumWRSectors(void)
|
||
{
|
||
PRINTDEBUG( " ACMD22 (SEND_NUM_WR_SECTORS)\n");
|
||
/* Argument(31:0) = stuff bits */
|
||
SD_TransReadyFPGA(); /* 関連レジスタ初期化 */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BRE)); /* SDカードからのデータ読込み要求割込み許可 */
|
||
|
||
SD_TransCommand((SD_CMD_ACMD | SEND_NUM_WR_SECTORS)); /* ACMD22(書きこみ完了セクタ数取得コマンド)発行、レスポンス(R1)待ち */
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: SD_MultiWriteBlock
|
||
|
||
Description: send multiple block write command.
|
||
マルチブロックライトコマンド発行。この後カードに
|
||
DATライン経由でデータを送信する必要がある。
|
||
|
||
Arguments: ulOffset : offset address to write(BYTE).
|
||
|
||
Returns: 0 : success
|
||
> 0 : error code
|
||
*---------------------------------------------------------------------------*/
|
||
u16 SD_MultiWriteBlock(u32 ulOffset)
|
||
{
|
||
PRINTDEBUG( " CMD25 (WRITE_MULTIPLE_BLOCK)\n");
|
||
|
||
SD_TransReadyFPGA(); /* INFOレジスタ初期化 */
|
||
// if( !SDCARD_UseFifoFlag) { /* FIFOを使わないとき */
|
||
SD_AndFPGA(SD_INFO2_MASK,(~SD_INFO2_MASK_BWE)); /* SDカードからのデータ書込み要求割込み許可 */
|
||
// }
|
||
|
||
/* 書き込み開始オフセット設定 */
|
||
SD_SetFPGA(SD_ARG0,(((LELONG *)&ulOffset)->dt2word.low));
|
||
SD_SetFPGA(SD_ARG1,(((LELONG *)&ulOffset)->dt2word.high));
|
||
|
||
SD_TransCommand(WRITE_MULTIPLE_BLOCK); /* CMD25(マルチセクタライトコマンド)発行 */
|
||
|
||
return SDCARD_ErrStatus;
|
||
}
|
||
|
||
|