mirror of
https://github.com/rvtr/twl_wrapsdk.git
synced 2025-10-31 06:11:10 -04:00
add nand interface for RTFS
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@137 4ee2a332-4b2b-5046-8439-1ba90f034370
This commit is contained in:
parent
3d9d0f4829
commit
29e5aff217
@ -31,7 +31,8 @@ SRCDIR = ../common/src src
|
||||
SRCS = \
|
||||
sdmc.c \
|
||||
sdif.c \
|
||||
drsdmc.c
|
||||
drsdmc.c \
|
||||
drnand.c \
|
||||
|
||||
TARGET_LIB = libsd_sp$(TWL_LIBSUFFIX).a
|
||||
|
||||
|
||||
632
build/libraries/devices/sdmc/ARM7/drnand.c
Normal file
632
build/libraries/devices/sdmc/ARM7/drnand.c
Normal file
@ -0,0 +1,632 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: CTR - rtfs interface for SD Memory Card
|
||||
File: drnand.h
|
||||
|
||||
Copyright 2006,2007 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <twl/rtfs.h>
|
||||
#include <portconf.h>
|
||||
//#if (INCLUDE_SD)
|
||||
|
||||
#include "sdmc_config.h"
|
||||
#include <twl/sdmc.h>
|
||||
#include "sdif_ip.h"
|
||||
#include "sdif_reg.h"
|
||||
|
||||
#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 NUM_SD_PAGES
|
||||
#define SD_PAGE_SIZE
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
extern変数
|
||||
*---------------------------------------------------------------------------*/
|
||||
extern int rtfs_first_stat_flag[26];
|
||||
|
||||
/*SDメモリカードのスペック構造体*/
|
||||
extern SdmcSpec sdmc_current_spec;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
extern関数
|
||||
*---------------------------------------------------------------------------*/
|
||||
extern SDMC_ERR_CODE sdmcGoIdle(void (*func1)(),void (*func2)());
|
||||
extern void i_sdmcCalcSize( void); //TODO:sdmc_current_specを構造体に入れること
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
static変数
|
||||
*---------------------------------------------------------------------------*/
|
||||
static int nand_drive_no;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
static関数
|
||||
*---------------------------------------------------------------------------*/
|
||||
static void sdi_get_CHS_params( void);
|
||||
static u32 sdi_get_ceil( u32 cval, u32 mval);
|
||||
static void sdi_get_nom( void);
|
||||
static void sdi_get_fatparams( void);
|
||||
static void sdi_build_partition_table( void);
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandCheckMedia
|
||||
|
||||
Description: MBRのシグネチャおよび
|
||||
パーティションのフォーマット種別をチェックする
|
||||
|
||||
Arguments:
|
||||
|
||||
Returns: TRUE/FALSE
|
||||
(FALSEなら pc_format_media が必要)
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL nandCheckMedia( void)
|
||||
{
|
||||
u16 i;
|
||||
SdmcResultInfo SdResult;
|
||||
u8* bufp;
|
||||
u32 buffer[512/4];
|
||||
u8 systemid;
|
||||
|
||||
/**/
|
||||
sdmcSelect( (u16)SDMC_PORT_NAND);
|
||||
|
||||
/**/
|
||||
if( sdmcReadFifo( buffer, 1, 0, NULL, &SdResult)) {
|
||||
return( FALSE);
|
||||
}
|
||||
|
||||
bufp = (u8*)buffer;
|
||||
|
||||
/* Check the Signature Word. */
|
||||
if( (bufp[510]!=0x55) || (bufp[511]!=0xAA)) {
|
||||
return( FALSE);
|
||||
}
|
||||
/* Check the System ID of partition. */
|
||||
systemid = bufp[450];
|
||||
if( (systemid!=0x01) && (systemid!=0x04) && (systemid!=0x06) &&
|
||||
(systemid!=0x0B) && (systemid!=0x0C)) {
|
||||
return( FALSE);
|
||||
}
|
||||
/* Check the System ID of unuse partitions. */
|
||||
for( i=1; i<4; i++) {
|
||||
systemid = bufp[450+(16*i)];
|
||||
if( systemid != 0x00) {
|
||||
return( FALSE);
|
||||
}
|
||||
}
|
||||
/**/
|
||||
/*もっと厳密にチェックするならパーティション0開始位置の
|
||||
正当性も調べる*/
|
||||
return( TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandRtfsIo
|
||||
|
||||
Description: 上位層からのセクタリード/ライト要求を受ける
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
block : 開始ブロック番号
|
||||
buffer :
|
||||
count : ブロック数
|
||||
reading : リード要求時にTRUE
|
||||
|
||||
Returns: TRUE/FALSE
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL nandRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading)
|
||||
{
|
||||
u16 result;
|
||||
SdmcResultInfo SdResult;
|
||||
|
||||
/**/
|
||||
sdmcSelect( (u16)SDMC_PORT_NAND);
|
||||
|
||||
if( reading) {
|
||||
PRINTDEBUG( "DEVCTL_IO_READ ... block:%x, count:%x -> buf:%x\n", block, count, buffer);
|
||||
result = sdmcReadFifo( buffer, count, block, NULL, &SdResult);
|
||||
// result = sdmcRead( buffer, count, block, NULL, &SdResult);
|
||||
}else{
|
||||
PRINTDEBUG( "DEVCTL_IO_WRITE ... block:%x, count:%x <- buf:%x\n", block, count, buffer);
|
||||
result = sdmcWriteFifo( buffer, count, block, NULL, &SdResult);
|
||||
// result = sdmcWrite( buffer, count, block, NULL, &SdResult);
|
||||
}
|
||||
if( result) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandRtfsCtrl
|
||||
|
||||
Description: 上位層からのコントロール要求を受ける
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
opcode : 要求の種類
|
||||
pargs :
|
||||
|
||||
Returns:
|
||||
Memo : DRIVE_FLAGS_REMOVABLEの場合、ドライバのIO関数を呼ぶ前に
|
||||
CTRL関数のDEVCTL_CHECK_STATUSが呼ばれる。
|
||||
DEVTEST_CHANGED→DEVTEST_NOCHANGEが確認されるとRTFSはセクタ0を
|
||||
読みに行き、FATパラメータを取得した上で目的のセクタを読みに行く。
|
||||
CTRL関数の前にはDEVCTL_CHECK_STATUSが呼ばれないので、DEVCTL_
|
||||
GET_GEOMETRYでは自前で再挿入をチェックする必要がある。
|
||||
*---------------------------------------------------------------------------*/
|
||||
int nandRtfsCtrl( int driveno, int opcode, void* pargs)
|
||||
{
|
||||
DDRIVE *pdr;
|
||||
DEV_GEOMETRY gc;
|
||||
int heads, secptrack;
|
||||
|
||||
/**/
|
||||
sdmcSelect( (u16)SDMC_PORT_NAND);
|
||||
|
||||
pdr = pc_drno_to_drive_struct( driveno);
|
||||
|
||||
switch( opcode) {
|
||||
case DEVCTL_GET_GEOMETRY: //formatまたはpartirionするときにRTFSが使うパラメータ
|
||||
PRINTDEBUG( "DEVCTL_GET_GEOMETRY\n");
|
||||
|
||||
rtfs_memset( &gc, (byte)0, sizeof(gc));
|
||||
|
||||
i_sdmcCalcSize(); //TODO:sdmc_current_specを構造体に入れること
|
||||
sdi_get_CHS_params(); //最初に呼ぶこと
|
||||
sdi_get_fatparams();
|
||||
sdi_get_nom();
|
||||
|
||||
PRINTDEBUG( "heads : 0x%x\n", sdmc_current_spec.heads);
|
||||
PRINTDEBUG( "secptrack : 0x%x\n", sdmc_current_spec.secptrack);
|
||||
PRINTDEBUG( "cylinders : 0x%x\n", sdmc_current_spec.cylinders);
|
||||
PRINTDEBUG( "SC : 0x%x\n", sdmc_current_spec.SC);
|
||||
PRINTDEBUG( "BU : 0x%x\n", sdmc_current_spec.BU);
|
||||
PRINTDEBUG( "RDE : 0x%x\n", sdmc_current_spec.RDE);
|
||||
PRINTDEBUG( "SS : 0x%x\n", sdmc_current_spec.SS);
|
||||
PRINTDEBUG( "RSC : 0x%x\n", sdmc_current_spec.RSC);
|
||||
PRINTDEBUG( "FATBITS : 0x%x\n", sdmc_current_spec.FATBITS);
|
||||
PRINTDEBUG( "SF : 0x%x\n", sdmc_current_spec.SF);
|
||||
PRINTDEBUG( "SSA : 0x%x\n", sdmc_current_spec.SSA);
|
||||
PRINTDEBUG( "NOM : 0x%x\n", sdmc_current_spec.NOM);
|
||||
|
||||
gc.dev_geometry_lbas = (sdmc_current_spec.adjusted_memory_capacity);// - sdmc_current_spec.NOM);
|
||||
gc.dev_geometry_heads = sdmc_current_spec.heads;
|
||||
gc.dev_geometry_cylinders = sdmc_current_spec.cylinders;
|
||||
gc.dev_geometry_secptrack = sdmc_current_spec.secptrack;
|
||||
/**/
|
||||
gc.fmt_parms_valid = TRUE;
|
||||
gc.fmt.oemname[0] = 'T';
|
||||
gc.fmt.oemname[1] = 'W';
|
||||
gc.fmt.oemname[2] = 'L';
|
||||
gc.fmt.oemname[3] = '\0';
|
||||
gc.fmt.secpalloc = sdmc_current_spec.SC; /*sectors per cluster(FIX by capacity)*/
|
||||
gc.fmt.secreserved = sdmc_current_spec.RSC;//sdmc_current_spec.RSC;/*reserved sectors(FIX 1 at FAT12,16)*/
|
||||
gc.fmt.numfats = 2;
|
||||
gc.fmt.secpfat = sdmc_current_spec.SF;
|
||||
gc.fmt.numhide = sdmc_current_spec.NOM; /**/
|
||||
gc.fmt.numroot = sdmc_current_spec.RDE; /*FIX*/
|
||||
gc.fmt.mediadesc = 0xF8;
|
||||
gc.fmt.secptrk = sdmc_current_spec.secptrack; //CHS Recommendation
|
||||
gc.fmt.numhead = sdmc_current_spec.heads;
|
||||
gc.fmt.numcyl = sdmc_current_spec.cylinders;
|
||||
gc.fmt.physical_drive_no = driveno;
|
||||
gc.fmt.binary_volume_label = BIN_VOL_LABEL;
|
||||
gc.fmt.text_volume_label[0] = '\0';
|
||||
//TODO:dev_geometry_lbasもセットする必要あるか調べること
|
||||
PRINTDEBUG( "heads : 0x%x, secptrack : 0x%x, cylinders : 0x%x\n", gc.dev_geometry_heads, gc.dev_geometry_secptrack, gc.dev_geometry_cylinders);
|
||||
|
||||
#if (TARGET_OS_CTR == 1)
|
||||
miCpuCopy8( &gc, pargs, sizeof(gc));
|
||||
// copybuff( pargs, &gc, sizeof(gc));
|
||||
#else
|
||||
MI_CpuCopy8( &gc, pargs, sizeof(gc));
|
||||
#endif
|
||||
return( 0);
|
||||
|
||||
case DEVCTL_FORMAT:
|
||||
PRINTDEBUG( "DEVCTL_FORMAT\n");
|
||||
sdi_build_partition_table(); //MBRセクタ(パーティションテーブル含む)書き込み
|
||||
return( 0);
|
||||
|
||||
case DEVCTL_REPORT_REMOVE: //抜かれたとき
|
||||
PRINTDEBUG( "DEVCTL_REPORT_REMOVE\n");
|
||||
pdr->drive_flags &= ~DRIVE_FLAGS_INSERTED;
|
||||
return( 0);
|
||||
|
||||
case DEVCTL_CHECKSTATUS: //REMOVABLEの場合、毎回R/W前に呼ばれる
|
||||
PRINTDEBUG( "DEVCTL_CHECKSTATUS\n");
|
||||
if (!(pdr->drive_flags & DRIVE_FLAGS_REMOVABLE)) { //リムーバブルでない場合
|
||||
return(DEVTEST_NOCHANGE);
|
||||
}
|
||||
if( rtfs_first_stat_flag[driveno]) { //初回のCHECKSTATUS時
|
||||
rtfs_first_stat_flag[driveno] = 0;
|
||||
PRINTDEBUG( "CHANGED!\n");
|
||||
return(DEVTEST_CHANGED);
|
||||
}else{
|
||||
PRINTDEBUG( "DEVTEST_NOCHANGE\n");
|
||||
return( DEVTEST_NOCHANGE);
|
||||
}
|
||||
|
||||
case DEVCTL_WARMSTART: //attachのときしか呼ばれない
|
||||
PRINTDEBUG( "DEVCTL_WARMSTART\n");
|
||||
/*-- GoIdleセット --*/
|
||||
sdmcGoIdle( NULL, NULL); //カード初期化シーケンス TODO:1ポートだけにする
|
||||
/*------------------*/
|
||||
pdr->drive_flags |= (DRIVE_FLAGS_VALID | DRIVE_FLAGS_REMOVABLE | DRIVE_FLAGS_PARTITIONED);
|
||||
pdr->partition_number = 0;
|
||||
|
||||
pdr->drive_flags |= DRIVE_FLAGS_INSERTED;
|
||||
return( 0);
|
||||
|
||||
case DEVCTL_POWER_RESTORE:
|
||||
PRINTDEBUG( "DEVCTL_POWER_RESTORE\n");
|
||||
break;
|
||||
|
||||
case DEVCTL_POWER_LOSS:
|
||||
PRINTDEBUG( "DEVCTL_POWER_LOSS\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTDEBUG( "DEVCTL_unknown\n");
|
||||
break;
|
||||
}
|
||||
return( 0);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: nandRtfsAttach
|
||||
|
||||
Description: sdmcドライバをドライブに割り当てる
|
||||
|
||||
Arguments: driveno : ドライブ番号
|
||||
|
||||
Returns:
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL nandRtfsAttach( int driveno)
|
||||
{
|
||||
BOOLEAN result;
|
||||
DDRIVE pdr;
|
||||
|
||||
pdr.dev_table_drive_io = nandRtfsIo;
|
||||
pdr.dev_table_perform_device_ioctl = nandRtfsCtrl;
|
||||
pdr.register_file_address = (dword) 0; /* Not used */
|
||||
pdr.interrupt_number = 0; /* Not used */
|
||||
pdr.drive_flags = 0;//DRIVE_FLAGS_FAILSAFE;
|
||||
pdr.partition_number = 0; /* Not used */
|
||||
pdr.pcmcia_slot_number = 0; /* Not used */
|
||||
pdr.controller_number = 0;
|
||||
pdr.logical_unit_number = 0;
|
||||
|
||||
result = rtfs_attach( driveno, &pdr, "SD1"); //構造体がFSライブラリ側にコピーされる
|
||||
|
||||
/*drivenoをグローバル変数に記憶*/
|
||||
nand_drive_no = driveno;
|
||||
|
||||
return( result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*SD File System Specification(仕様書)に基づいた値を出す*/
|
||||
static void sdi_get_CHS_params( void)
|
||||
{
|
||||
int mbytes;
|
||||
|
||||
// mbytes = (sdmc_current_spec.card_capacity / (1024 * 1024)) * 512;
|
||||
mbytes = (sdmc_current_spec.card_capacity >> 11);
|
||||
|
||||
while( 1) {
|
||||
if( mbytes <= 2) {
|
||||
sdmc_current_spec.heads = 2;
|
||||
sdmc_current_spec.secptrack = 16;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 16) {
|
||||
sdmc_current_spec.heads = 2;
|
||||
sdmc_current_spec.secptrack = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 32) {
|
||||
sdmc_current_spec.heads = 4;
|
||||
sdmc_current_spec.secptrack = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 128) {
|
||||
sdmc_current_spec.heads = 8;
|
||||
sdmc_current_spec.secptrack = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 256) {
|
||||
sdmc_current_spec.heads = 16;
|
||||
sdmc_current_spec.secptrack = 32;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 504) {
|
||||
sdmc_current_spec.heads = 16;
|
||||
sdmc_current_spec.secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 1008) {
|
||||
sdmc_current_spec.heads = 32;
|
||||
sdmc_current_spec.secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 2016) {
|
||||
sdmc_current_spec.heads = 64;
|
||||
sdmc_current_spec.secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 2048) {
|
||||
sdmc_current_spec.heads = 128;
|
||||
sdmc_current_spec.secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 4032) {
|
||||
sdmc_current_spec.heads = 128;
|
||||
sdmc_current_spec.secptrack = 63;
|
||||
break;
|
||||
}
|
||||
if( mbytes <= 32768) {
|
||||
sdmc_current_spec.heads = 255;
|
||||
sdmc_current_spec.secptrack = 63;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*シリンダ数を計算*/
|
||||
sdmc_current_spec.cylinders = (sdmc_current_spec.memory_capacity /
|
||||
(sdmc_current_spec.heads * sdmc_current_spec.secptrack));
|
||||
|
||||
/*memory_capacityを再計算してadjusted_memory_capacityに格納*/
|
||||
sdmc_current_spec.adjusted_memory_capacity = sdmc_current_spec.cylinders *
|
||||
(sdmc_current_spec.heads * sdmc_current_spec.secptrack);
|
||||
}
|
||||
|
||||
|
||||
/*引数を超える最も小さい整数を算出する*/
|
||||
static u32 sdi_get_ceil( u32 cval, u32 mval)
|
||||
{
|
||||
return( (cval / mval) + (1 * (cval % mval != 0)));
|
||||
}
|
||||
|
||||
|
||||
/*マスターブートセクタのセクタ数を返す*/
|
||||
static void sdi_get_nom( void)
|
||||
{
|
||||
u32 RSC = 1; //FAT12,16では1
|
||||
u32 RDE = 512; //ルートディレクトリエントリ。FIX
|
||||
u32 SS = 512; //セクタサイズ。FIX
|
||||
u32 TS, SC, n;
|
||||
u32 MAX, SFdash;
|
||||
|
||||
TS = sdmc_current_spec.adjusted_memory_capacity;
|
||||
SC = sdmc_current_spec.SC;
|
||||
|
||||
sdmc_current_spec.SF = sdi_get_ceil( TS/SC * sdmc_current_spec.FATBITS, SS*8);
|
||||
|
||||
/*-----------------------SDHCのとき----------------------------*/
|
||||
if( sdmc_current_spec.csd_ver2_flag) {
|
||||
sdmc_current_spec.NOM = sdmc_current_spec.BU;
|
||||
do {
|
||||
n = sdi_get_ceil( 2*sdmc_current_spec.SF, sdmc_current_spec.BU);
|
||||
sdmc_current_spec.RSC = (sdmc_current_spec.BU * n) - ( 2 * sdmc_current_spec.SF);
|
||||
if( sdmc_current_spec.RSC < 9) {
|
||||
sdmc_current_spec.RSC += sdmc_current_spec.BU;
|
||||
}
|
||||
sdmc_current_spec.SSA = sdmc_current_spec.RSC + (2 * sdmc_current_spec.SF);
|
||||
do {
|
||||
MAX = ((TS - sdmc_current_spec.NOM - sdmc_current_spec.SSA) / SC) + 1;
|
||||
SFdash = sdi_get_ceil( (2+(MAX-1)) * sdmc_current_spec.FATBITS, SS*8);
|
||||
if( SFdash > sdmc_current_spec.SF) {
|
||||
sdmc_current_spec.SSA += sdmc_current_spec.BU;
|
||||
sdmc_current_spec.RSC += sdmc_current_spec.BU;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}while( 1);
|
||||
if( SFdash != sdmc_current_spec.SF) {
|
||||
sdmc_current_spec.SF -= 1;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}while( 1);
|
||||
}else{ /*-------------------------SDのとき-------------------------------*/
|
||||
do {
|
||||
sdmc_current_spec.SSA = RSC + ( 2 * sdmc_current_spec.SF) + sdi_get_ceil( 32*RDE, SS);
|
||||
n = sdi_get_ceil( sdmc_current_spec.SSA, sdmc_current_spec.BU);
|
||||
sdmc_current_spec.NOM = (sdmc_current_spec.BU * n) - sdmc_current_spec.SSA;
|
||||
if( sdmc_current_spec.NOM != sdmc_current_spec.BU) {
|
||||
sdmc_current_spec.NOM += sdmc_current_spec.BU;
|
||||
}
|
||||
do {
|
||||
MAX = ((TS - sdmc_current_spec.NOM - sdmc_current_spec.SSA) / SC) + 1;
|
||||
SFdash = sdi_get_ceil( (2+(MAX-1)) * sdmc_current_spec.FATBITS, SS*8);
|
||||
if( SFdash > sdmc_current_spec.SF) {
|
||||
sdmc_current_spec.NOM += sdmc_current_spec.BU;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}while( 1);
|
||||
if( SFdash != sdmc_current_spec.SF) {
|
||||
sdmc_current_spec.SF = SFdash;
|
||||
}else{
|
||||
break; //complete
|
||||
}
|
||||
}while( 1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*FATのビット数を返す*/
|
||||
static void sdi_get_fatparams( void)
|
||||
{
|
||||
int mbytes;
|
||||
|
||||
// mbytes = (sdmc_current_spec.card_capacity / (1024 * 1024)) * 512;
|
||||
mbytes = (sdmc_current_spec.card_capacity >> 11);
|
||||
|
||||
if( mbytes <= 64) {
|
||||
sdmc_current_spec.FATBITS = 12;
|
||||
sdmc_current_spec.RDE = 512;
|
||||
sdmc_current_spec.RSC = 1;
|
||||
}else{
|
||||
if( mbytes <= 2048) {
|
||||
sdmc_current_spec.FATBITS = 16;
|
||||
sdmc_current_spec.RDE = 512;
|
||||
sdmc_current_spec.RSC = 1;
|
||||
}else{
|
||||
sdmc_current_spec.FATBITS = 32;
|
||||
sdmc_current_spec.RDE = 0; //FAT32のときは未使用。0にしておかないとRTFSが BAD FORMAT を返す。
|
||||
sdmc_current_spec.RSC = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( mbytes <= 8) {
|
||||
sdmc_current_spec.SC = 16;
|
||||
sdmc_current_spec.BU = 16;
|
||||
return;
|
||||
}
|
||||
if( mbytes <= 64) {
|
||||
sdmc_current_spec.SC = 32;
|
||||
sdmc_current_spec.BU = 32;
|
||||
return;
|
||||
}
|
||||
if( mbytes <= 256) {
|
||||
sdmc_current_spec.SC = 32;
|
||||
sdmc_current_spec.BU = 64;
|
||||
return;
|
||||
}
|
||||
if( mbytes <= 1024) {
|
||||
sdmc_current_spec.SC = 32;
|
||||
sdmc_current_spec.BU = 128;
|
||||
return;
|
||||
}
|
||||
if( mbytes <= 2048) {
|
||||
sdmc_current_spec.SC = 64;
|
||||
sdmc_current_spec.BU = 128;
|
||||
return;
|
||||
}
|
||||
if( mbytes <= 32768) {
|
||||
sdmc_current_spec.SC = 64;
|
||||
sdmc_current_spec.BU = 8192;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*MBRセクタ(パーティションセクタ含む)を生成して書き込む*/
|
||||
static void sdi_build_partition_table( void)
|
||||
{
|
||||
u16 MbrSectDat[512/2];
|
||||
u32 starting_head, starting_sect, starting_cyl;
|
||||
u32 ending_head, ending_sect, ending_cyl;
|
||||
u32 total_sect;
|
||||
#if (SD_DEBUG_PRINT_ON == 1)
|
||||
u32 starting_data, ending_data;
|
||||
#endif
|
||||
u32 systemid;
|
||||
SdmcResultInfo SdResult;
|
||||
|
||||
/**/
|
||||
starting_head = sdmc_current_spec.NOM % (sdmc_current_spec.heads *
|
||||
sdmc_current_spec.secptrack);
|
||||
starting_head /= sdmc_current_spec.secptrack;
|
||||
|
||||
/**/
|
||||
starting_sect = (sdmc_current_spec.NOM % sdmc_current_spec.secptrack) + 1;
|
||||
|
||||
/**/
|
||||
starting_cyl = sdmc_current_spec.NOM / (sdmc_current_spec.heads *
|
||||
sdmc_current_spec.secptrack);
|
||||
|
||||
/**/
|
||||
total_sect = (sdmc_current_spec.adjusted_memory_capacity - sdmc_current_spec.NOM);
|
||||
ending_head = (sdmc_current_spec.NOM + total_sect - 1) %
|
||||
(sdmc_current_spec.heads * sdmc_current_spec.secptrack);
|
||||
ending_head /= sdmc_current_spec.secptrack;
|
||||
|
||||
/**/
|
||||
ending_sect = ((sdmc_current_spec.NOM + total_sect - 1) %
|
||||
sdmc_current_spec.secptrack) + 1;
|
||||
|
||||
/**/
|
||||
ending_cyl = (sdmc_current_spec.NOM + total_sect - 1) /
|
||||
(sdmc_current_spec.heads * sdmc_current_spec.secptrack);
|
||||
|
||||
/**/
|
||||
if( sdmc_current_spec.FATBITS == 32) { //FAT32のとき
|
||||
if( total_sect < 0xFB0400) { //8032.5MBが閾値(SD FileSystemSpec2.00参照)
|
||||
systemid = 0x0B; /* FAT32 */
|
||||
}else{
|
||||
systemid = 0x0C; /* FAT32(拡張INT13対応) */
|
||||
}
|
||||
}else{ //FAT12,FAT16のとき
|
||||
if( total_sect < 32680) {
|
||||
systemid = 0x01; /* FAT12 */
|
||||
}else if( total_sect < 65536) {
|
||||
systemid = 0x04; /* FAT16(16MB~32MB未満) */
|
||||
}else{
|
||||
systemid = 0x06; /* FAT16(32MB~4GB) */
|
||||
}
|
||||
}
|
||||
|
||||
/*MBRセクタ(パーティションテーブル含む)作成*/
|
||||
#if (TARGET_OS_CTR == 1)
|
||||
miCpuFill8( MbrSectDat, 0, 512);
|
||||
#else
|
||||
MI_CpuFill8( MbrSectDat, 0, 512);
|
||||
#endif
|
||||
MbrSectDat[446/2] = (starting_head<<8);
|
||||
//上位8bit:starting_cylの下位8bit, 下位8bit:starting_cylの上位2bit + starting_sect 6bit.
|
||||
MbrSectDat[448/2] = (starting_cyl<<8) + ((starting_cyl>>2) & 0xC0) + starting_sect;
|
||||
MbrSectDat[450/2] = (ending_head<<8) + systemid;
|
||||
//上位8bit:ending_cylの下位8bit, 下位8bit:ending_cylの上位2bit + ending_sect 6bit.
|
||||
MbrSectDat[452/2] = (ending_cyl<<8) + ((ending_cyl>>2) & 0xC0) + ending_sect;
|
||||
MbrSectDat[454/2] = sdmc_current_spec.NOM;
|
||||
MbrSectDat[456/2] = (sdmc_current_spec.NOM>>16);
|
||||
MbrSectDat[458/2] = total_sect;
|
||||
MbrSectDat[460/2] = (total_sect>>16);
|
||||
MbrSectDat[510/2] = 0xAA55;
|
||||
/*セクタ0に書き込み*/
|
||||
sdmcWriteFifo( MbrSectDat, 1, 0, NULL, &SdResult);
|
||||
|
||||
/**/
|
||||
PRINTDEBUG( "total sect : 0x%x\n", total_sect);
|
||||
PRINTDEBUG( "starting head : 0x%x\n", starting_head);
|
||||
PRINTDEBUG( "starting sect : 0x%x\n", starting_sect);
|
||||
PRINTDEBUG( "starting cyl : 0x%x\n", starting_cyl);
|
||||
PRINTDEBUG( "ending head : 0x%x\n", ending_head);
|
||||
PRINTDEBUG( "ending sect : 0x%x\n", ending_sect);
|
||||
PRINTDEBUG( "ending cyl : 0x%x\n", ending_cyl);
|
||||
PRINTDEBUG( "\n");
|
||||
#if (SD_DEBUG_PRINT_ON == 1)
|
||||
starting_data = (starting_cyl<<8) + ((starting_cyl>>2) & 0xC0) + starting_sect;
|
||||
PRINTDEBUG( "starting data : 0x%x\n", starting_data);
|
||||
ending_data = (ending_cyl<<8) + ((ending_cyl>>2) & 0xC0) + ending_sect;
|
||||
PRINTDEBUG( "endign data : 0x%x\n", ending_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
//#endif /*(INCLUDE_SD)*/
|
||||
@ -55,6 +55,7 @@ extern SdmcSpec sdmc_current_spec;
|
||||
extern関数
|
||||
*---------------------------------------------------------------------------*/
|
||||
extern SDMC_ERR_CODE sdmcGoIdle(void (*func1)(),void (*func2)());
|
||||
extern void i_sdmcCalcSize( void); //TODO:sdmc_current_specを構造体に入れること
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
@ -94,6 +95,9 @@ BOOL sdmcCheckMedia( void)
|
||||
u32 buffer[512/4];
|
||||
u8 systemid;
|
||||
|
||||
/**/
|
||||
sdmcSelect( (u16)SDMC_PORT_CARD);
|
||||
|
||||
/**/
|
||||
if( sdmcReadFifo( buffer, 1, 0, NULL, &SdResult)) {
|
||||
return( FALSE);
|
||||
@ -143,6 +147,9 @@ BOOL sdmcRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN rea
|
||||
u16 result;
|
||||
SdmcResultInfo SdResult;
|
||||
|
||||
/**/
|
||||
sdmcSelect( (u16)SDMC_PORT_CARD);
|
||||
|
||||
if( reading) {
|
||||
PRINTDEBUG( "DEVCTL_IO_READ ... block:%x, count:%x -> buf:%x\n", block, count, buffer);
|
||||
result = sdmcReadFifo( buffer, count, block, NULL, &SdResult);
|
||||
@ -182,6 +189,9 @@ int sdmcRtfsCtrl( int driveno, int opcode, void* pargs)
|
||||
DEV_GEOMETRY gc;
|
||||
int heads, secptrack;
|
||||
|
||||
/**/
|
||||
sdmcSelect( (u16)SDMC_PORT_CARD);
|
||||
|
||||
pdr = pc_drno_to_drive_struct( driveno);
|
||||
|
||||
switch( opcode) {
|
||||
@ -202,6 +212,7 @@ int sdmcRtfsCtrl( int driveno, int opcode, void* pargs)
|
||||
|
||||
rtfs_memset( &gc, (byte)0, sizeof(gc));
|
||||
|
||||
i_sdmcCalcSize(); //TODO:sdmc_current_specを構造体に入れること
|
||||
sdi_get_CHS_params(); //最初に呼ぶこと
|
||||
sdi_get_fatparams();
|
||||
sdi_get_nom();
|
||||
@ -225,9 +236,9 @@ int sdmcRtfsCtrl( int driveno, int opcode, void* pargs)
|
||||
gc.dev_geometry_secptrack = sdmc_current_spec.secptrack;
|
||||
/**/
|
||||
gc.fmt_parms_valid = TRUE;
|
||||
gc.fmt.oemname[0] = 'C';
|
||||
gc.fmt.oemname[1] = 'T';
|
||||
gc.fmt.oemname[2] = 'R';
|
||||
gc.fmt.oemname[0] = 'T';
|
||||
gc.fmt.oemname[1] = 'W';
|
||||
gc.fmt.oemname[2] = 'L';
|
||||
gc.fmt.oemname[3] = '\0';
|
||||
gc.fmt.secpalloc = sdmc_current_spec.SC; /*sectors per cluster(FIX by capacity)*/
|
||||
gc.fmt.secreserved = sdmc_current_spec.RSC;//sdmc_current_spec.RSC;/*reserved sectors(FIX 1 at FAT12,16)*/
|
||||
@ -300,7 +311,7 @@ int sdmcRtfsCtrl( int driveno, int opcode, void* pargs)
|
||||
if( func_SDCARD_Out != i_sdmcRemovedIntr) {
|
||||
func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得
|
||||
}
|
||||
sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス
|
||||
sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス TODO:1ポートだけにする
|
||||
/*------------------*/
|
||||
pdr->drive_flags |= (DRIVE_FLAGS_VALID | DRIVE_FLAGS_REMOVABLE | DRIVE_FLAGS_PARTITIONED);
|
||||
pdr->partition_number = 0;
|
||||
@ -373,7 +384,7 @@ BOOL sdmcRtfsAttach( int driveno)
|
||||
pdr.controller_number = 0;
|
||||
pdr.logical_unit_number = 0;
|
||||
|
||||
result = rtfs_attach( driveno, &pdr, "SD"); //構造体がFSライブラリ側にコピーされる
|
||||
result = rtfs_attach( driveno, &pdr, "SD0"); //構造体がFSライブラリ側にコピーされる
|
||||
|
||||
/*drivenoをグローバル変数に記憶*/
|
||||
sdmc_drive_no = driveno;
|
||||
|
||||
@ -103,7 +103,7 @@ typedef struct { //OSMessage
|
||||
/***********************************************************************
|
||||
static関数の宣言
|
||||
***********************************************************************/
|
||||
static void i_sdmcCalcSize( void);
|
||||
void i_sdmcCalcSize( void);
|
||||
static void SDCARD_Backup_port0(void);
|
||||
static void SDCARD_Backup_port1(void);
|
||||
static void SDCARD_Restore_port0(void);
|
||||
|
||||
@ -177,25 +177,6 @@ void TwlSpMain(void)
|
||||
|
||||
#else
|
||||
/*デバイスドライバの登録*/
|
||||
for( i=0; i<2; i++) {
|
||||
if( (i % 2) == 0) {
|
||||
/*NANDからブロックライト/リード*/
|
||||
result = sdmcSelect( (u16)SDMC_PORT_NAND);
|
||||
if( result != 0) {
|
||||
PRINTDEBUG( "sdmcSelect(NAND) failed.\n");
|
||||
}else{
|
||||
PRINTDEBUG( "sdmcSelect(NAND) success.\n");
|
||||
}
|
||||
}else{
|
||||
/*CARDからブロックライト/リード*/
|
||||
result = sdmcSelect( (u16)SDMC_PORT_CARD);
|
||||
if( result != 0) {
|
||||
PRINTDEBUG( "sdmcSelect(CARD) failed.\n");
|
||||
}else{
|
||||
PRINTDEBUG( "sdmcSelect(CARD) success.\n");
|
||||
}
|
||||
}
|
||||
|
||||
PRINTDEBUG( "attach start\n");
|
||||
if( sdmcRtfsAttach( 4) == FALSE) { //sdmcをEドライブにする
|
||||
PRINTDEBUG( "sdmcRtfsAttach failed.\n");
|
||||
@ -206,38 +187,62 @@ void TwlSpMain(void)
|
||||
PRINTDEBUG( "sdmcRtfsAttach error!.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if( !rtfs_pc_set_default_drive( (unsigned char*)"E:")) {
|
||||
PRINTDEBUG( "pc_set_default_drive failed\n");
|
||||
while( 1){};
|
||||
if( nandRtfsAttach( 5) == FALSE) { //nandをFドライブにする
|
||||
PRINTDEBUG( "nandRtfsAttach failed.\n");
|
||||
}else{
|
||||
if( nandRtfsAttach( 5) == FALSE) {
|
||||
PRINTDEBUG( "nandRtfsAttach success.\n");
|
||||
}else{
|
||||
PRINTDEBUG( "nandRtfsAttach error!.\n");
|
||||
}
|
||||
}
|
||||
PRINTDEBUG( "pc_set_default_drive success\n");
|
||||
|
||||
/**/
|
||||
PRINTDEBUG( "pc_check_disk start. please wait.\n");
|
||||
pc_check_disk( (byte*)"E:", &dstat, 0, 1, 1);
|
||||
PRINTDEBUG( "pc_check_disk end.\n");
|
||||
for( i=0; i<2; i++) {
|
||||
if( (i % 2) == 0) {
|
||||
/*SDからブロックライト/リード*/
|
||||
if( !rtfs_pc_set_default_drive( (unsigned char*)"E:")) {
|
||||
PRINTDEBUG( "pc_set_default_drive (E) failed\n");
|
||||
while( 1){};
|
||||
}
|
||||
PRINTDEBUG( "pc_set_default_drive (E) success\n");
|
||||
/**/
|
||||
PRINTDEBUG( "pc_check_disk start. please wait.\n");
|
||||
pc_check_disk( (byte*)"E:", &dstat, 0, 1, 1);
|
||||
PRINTDEBUG( "pc_check_disk end.\n");
|
||||
}else{
|
||||
/*NANDからブロックライト/リード*/
|
||||
if( !rtfs_pc_set_default_drive( (unsigned char*)"F:")) {
|
||||
PRINTDEBUG( "pc_set_default_drive (F) failed\n");
|
||||
while( 1){};
|
||||
}
|
||||
PRINTDEBUG( "pc_set_default_drive (F) success\n");
|
||||
/**/
|
||||
PRINTDEBUG( "pc_check_disk start. please wait.\n");
|
||||
pc_check_disk( (byte*)"F:", &dstat, 0, 1, 1);
|
||||
PRINTDEBUG( "pc_check_disk end.\n");
|
||||
}
|
||||
|
||||
/*----------*/
|
||||
fd = po_open( (byte*)"\\sdmc_twl_test.bin", (PO_CREAT|PO_BINARY|PO_WRONLY), PS_IWRITE);
|
||||
if( fd < 0) {
|
||||
PRINTDEBUG( "po_open failed.\n");
|
||||
while( 1) {};
|
||||
|
||||
/*----------*/
|
||||
fd = po_open( (byte*)"\\sdmc_twl_test.bin", (PO_CREAT|PO_BINARY|PO_WRONLY), PS_IWRITE);
|
||||
if( fd < 0) {
|
||||
PRINTDEBUG( "po_open failed.\n");
|
||||
while( 1) {};
|
||||
}
|
||||
PRINTDEBUG( "po_open success.\n");
|
||||
/*----------*/
|
||||
|
||||
/*----------*/
|
||||
if( po_close( fd) < 0) {
|
||||
PRINTDEBUG( "po_close failed.\n");
|
||||
while( 1) {};
|
||||
}
|
||||
PRINTDEBUG( "po_close success.\n");
|
||||
/*----------*/
|
||||
}
|
||||
PRINTDEBUG( "po_open success.\n");
|
||||
/*----------*/
|
||||
|
||||
/*----------*/
|
||||
if( po_close( fd) < 0) {
|
||||
PRINTDEBUG( "po_close failed.\n");
|
||||
while( 1) {};
|
||||
}
|
||||
PRINTDEBUG( "po_close success.\n");
|
||||
/*----------*/
|
||||
}
|
||||
#endif
|
||||
|
||||
PRINTDEBUG( "Sample program ends.\n");
|
||||
PRINTDEBUG( "Sample program ends.\n");
|
||||
|
||||
|
||||
while (TRUE)
|
||||
|
||||
@ -128,10 +128,15 @@ typedef struct {
|
||||
BOOL sdmcRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading);
|
||||
int sdmcRtfsCtrl( int driveno, int opcode, void* pargs);
|
||||
BOOL sdmcRtfsAttach( int driveno);
|
||||
|
||||
BOOL sdmcCheckMedia( void);
|
||||
|
||||
|
||||
BOOL nandRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading);
|
||||
int nandRtfsCtrl( int driveno, int opcode, void* pargs);
|
||||
BOOL nandRtfsAttach( int driveno);
|
||||
BOOL nandCheckMedia( void);
|
||||
|
||||
|
||||
/*********************************************
|
||||
Šî–{API
|
||||
*********************************************/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user