diff --git a/build/buildtools/commondefs b/build/buildtools/commondefs index be1d1c67..7e68f8ac 100644 --- a/build/buildtools/commondefs +++ b/build/buildtools/commondefs @@ -26,7 +26,7 @@ endif TWL_KEYSDIR ?= $(FIRM_ROOT)/keys/dummy -ifneq ($(filter NORFIRM NANDFIRM GCDFIRM,$(FIRM_TARGET)),) +ifneq ($(filter FIRM GCDFIRM,$(FIRM_TARGET)),) TARGET_BIN ?= $(subst .,$(DUMMY_KEYS_SUFFIX).,$(TARGET_FIRM_BIN)) endif @@ -41,10 +41,10 @@ SPACE ?= $(EMPTY) $(EMPTY) # FIRM_CODEGEN = [ARM/THUMB] # FIRM_PROC = [ARM9/ARM7] # -# FIRM_TARGET = [NORFIRM/NANDFIRM/GCDFIRM/APP] +# FIRM_TARGET = [FIRM/GCDFIRM/APP] # -FIRM_PLATFORM ?= BB +FIRM_PLATFORM ?= TS FIRM_MEMSIZE ?= 32M FIRM_CODEGEN ?= ARM FIRM_PROC ?= ARM9 @@ -164,6 +164,7 @@ ifeq ($(CODEGEN_PROC),ARM9) FIRM_LIBS_BASE ?= \ libos \ libmi \ + libpxi \ # libgcd \ # libacsign \ @@ -173,9 +174,12 @@ else # ($(CODEGEN_PROC),ARM7) FIRM_LIBS_BASE ?= \ libos_sp \ + libfatfs_sp \ + libpxi_sp \ + libaes_sp \ + libpm_sp \ # libnvram_sp \ # libgcd_sp \ -# libaes_sp \ # libacsign_sp \ # libfirmsd_sp \ diff --git a/build/libraries/Makefile b/build/libraries/Makefile index b2d6b7dd..727e589c 100644 --- a/build/libraries/Makefile +++ b/build/libraries/Makefile @@ -25,10 +25,13 @@ SUBDIRS = \ os \ mi \ init \ + pxi \ + fatfs \ + aes \ + pm \ # syscall \ # nvram \ # gcd \ -# aes \ # acsign \ # acsign_ecc \ # devices \ diff --git a/build/libraries/aes/ARM7/Makefile b/build/libraries/aes/ARM7/Makefile new file mode 100644 index 00000000..ea3b9ba8 --- /dev/null +++ b/build/libraries/aes/ARM7/Makefile @@ -0,0 +1,59 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - libraries - aes +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +SUBDIRS = +SUBMAKES = + + +#---------------------------------------------------------------------------- + +# build ARM & THUMB libraries +FIRM_CODEGEN_ALL ?= TRUE + +# Codegen for sub processer +FIRM_PROC = ARM7 + +SRCDIR = . + +SRCS = \ + aes_init.c \ + +TARGET_LIB = libaes_sp$(FIRM_LIBSUFFIX).a + +#---------------------------------------------------------------------------- + +# DEBUG版ビルドの場合、RELEASE版でビルドして +# DEBUG版のライブラリを装います。 + +ifdef NITRO_DEBUG +NITRO_BUILD_TYPE = RELEASE +endif + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_TARGETS = $(TARGETS) +INSTALL_DIR = $(FIRM_INSTALL_LIBDIR) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + +#===== End of Makefile ===== diff --git a/build/libraries/aes/ARM7/aes_init.c b/build/libraries/aes/ARM7/aes_init.c new file mode 100644 index 00000000..9f37d4c4 --- /dev/null +++ b/build/libraries/aes/ARM7/aes_init.c @@ -0,0 +1,72 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - libraries - aes + File: aes_init.c + + Copyright 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. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include + +/*---------------------------------------------------------------------------* + Name: AESi_InitGameKeys + + Description: set IDs depending on the application. + you SHOULD NOT touch any ID registers after this call. + + Arguments: u8[4] game code + + Returns: None + *---------------------------------------------------------------------------*/ +void AESi_InitGameKeys( u8 game_code[4] ) +{ + while (reg_AES_AES_CNT & REG_AES_AES_CNT_E_MASK) + { + } + + reg_AES_AES_ID_B2 = AES_IDS_ID0_C(game_code); + reg_AES_AES_ID_B3 = AES_IDS_ID0_D(game_code); + + reg_AES_AES_ID_C0 = AES_IDS_ID1_A(game_code); + reg_AES_AES_ID_C1 = AES_IDS_ID1_B(game_code); + + // set dummy without seed[3] + reg_AES_AES_SEED_A0 = 1; + reg_AES_AES_SEED_A1 = 2; + reg_AES_AES_SEED_A2 = 3; + reg_AES_AES_SEED_B0 = 4; + reg_AES_AES_SEED_B1 = 5; + reg_AES_AES_SEED_B2 = 6; + reg_AES_AES_SEED_C0 = 7; + reg_AES_AES_SEED_C1 = 8; + reg_AES_AES_SEED_C2 = 9; + reg_AES_AES_SEED_D0 = 10; + reg_AES_AES_SEED_D1 = 11; + reg_AES_AES_SEED_D2 = 12; + + reg_AES_AES_KEY_A0 = 1; + reg_AES_AES_KEY_A1 = 2; + reg_AES_AES_KEY_A2 = 3; + reg_AES_AES_KEY_A3 = 3; + reg_AES_AES_KEY_B0 = 4; + reg_AES_AES_KEY_B1 = 5; + reg_AES_AES_KEY_B2 = 6; + reg_AES_AES_KEY_B3 = 6; + reg_AES_AES_KEY_C0 = 7; + reg_AES_AES_KEY_C1 = 8; + reg_AES_AES_KEY_C2 = 9; + reg_AES_AES_KEY_C3 = 9; + reg_AES_AES_KEY_D0 = 10; + reg_AES_AES_KEY_D1 = 11; + reg_AES_AES_KEY_D2 = 12; + reg_AES_AES_KEY_D3 = 12; +} diff --git a/build/libraries/aes/Makefile b/build/libraries/aes/Makefile new file mode 100644 index 00000000..f45f5240 --- /dev/null +++ b/build/libraries/aes/Makefile @@ -0,0 +1,31 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlIPL - libraries - aes +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = ARM7 + +#---------------------------------------------------------------------------- + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/libraries/fatfs/ARM7/Makefile b/build/libraries/fatfs/ARM7/Makefile new file mode 100644 index 00000000..9bf6af19 --- /dev/null +++ b/build/libraries/fatfs/ARM7/Makefile @@ -0,0 +1,68 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - libraries - fatfs +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +SUBDIRS = +SUBMAKES = + + +#---------------------------------------------------------------------------- + +# build ARM & THUMB libraries +FIRM_CODEGEN_ALL ?= TRUE + +# Codegen for sub processer +FIRM_PROC = ARM7 + +INCDIR = rom_sdmc \ + $(TWLSDK_ROOT)/build/libraries/fatfs/ARM7.TWL/include \ + $(TWLSDK_ROOT)/build/libraries/fatfs/ARM7.TWL/include/twl/fatfs/ARM7 + +SRCDIR = src rom_sdmc + +SRCS = \ + fatfs_loader.c \ + fatfs_firm.c \ + sdmc.c \ + sdmc_nandinit.c \ + drsdmc.c \ + + +TARGET_LIB = libfatfs_sp$(FIRM_LIBSUFFIX).a + +#---------------------------------------------------------------------------- + +# DEBUG版ビルドの場合、RELEASE版でビルドして +# DEBUG版のライブラリを装います。 + +ifdef NITRO_DEBUG +NITRO_BUILD_TYPE = RELEASE +endif + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_TARGETS = $(TARGETS) +INSTALL_DIR = $(FIRM_INSTALL_LIBDIR) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + +#===== End of Makefile ===== diff --git a/build/libraries/fatfs/ARM7/firm_sdmc/drsdmc.c b/build/libraries/fatfs/ARM7/firm_sdmc/drsdmc.c new file mode 100644 index 00000000..3087226e --- /dev/null +++ b/build/libraries/fatfs/ARM7/firm_sdmc/drsdmc.c @@ -0,0 +1,687 @@ +/*---------------------------------------------------------------------------* + Project: CTR - rtfs interface for SD Memory Card + File: drsdmc.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 +#include +//#if (INCLUDE_SD) + +//#include "sdmc_config.h" +//#include "sdmc.h" +//#include "sdif_ip.h" +//#include "sdif_reg.h" +#include + +#if (SD_DEBUG_PRINT_ON == 1) + #if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + #define PRINTDEBUG osTPrintf + #else + #include + #define PRINTDEBUG vlink_dos_printf + #endif +#else + #define PRINTDEBUG( ...) ((void)0) +#endif + + +#define NUM_SD_PAGES +#define SD_PAGE_SIZE + + +/*---------------------------------------------------------------------------* + extern変数 + *---------------------------------------------------------------------------*/ +//extern ER_ID sdmc_dtq_id; +//extern ER_ID sdmc_result_dtq_id; +extern void (*func_SDCARD_In)(void); /* カード挿入イベント用コールバック保存用 */ +extern void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */ +extern volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ + +extern int rtfs_first_stat_flag[26]; + +/*SDメモリカードのスペック構造体*/ +extern SdmcSpec sdmc_current_spec; + + +/*---------------------------------------------------------------------------* + extern関数 + *---------------------------------------------------------------------------*/ +extern SDMC_ERR_CODE sdmcGoIdle(void (*func1)(),void (*func2)()); + + +/*---------------------------------------------------------------------------* + static変数 + *---------------------------------------------------------------------------*/ +static int sdmc_drive_no; +void (*func_usr_sdmc_out)(void) = NULL; /* カード排出イベントのユーザコールバック */ + + +/*---------------------------------------------------------------------------* + static関数 + *---------------------------------------------------------------------------*/ +void i_sdmcRemovedIntr( void); +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: sdmcCheckMedia + + Description: MBRのシグネチャおよび + パーティションのフォーマット種別をチェックする + + Arguments: + + Returns: TRUE/FALSE + (FALSEなら pc_format_media が必要) + *---------------------------------------------------------------------------*/ +BOOL sdmcCheckMedia( void) +{ + u16 i; + SdmcResultInfo SdResult; + u8* bufp; + u32 buffer[512/4]; + u8 systemid; + + /**/ + 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: sdmcRtfsIo + + Description: 上位層からのセクタリード/ライト要求を受ける + + Arguments: driveno : ドライブ番号 + block : 開始ブロック番号 + buffer : + count : ブロック数 + reading : リード要求時にTRUE + + Returns: TRUE/FALSE + *---------------------------------------------------------------------------*/ +BOOL sdmcRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading) +{ + u16 result; + SdmcResultInfo SdResult; + + 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: sdmcRtfsCtrl + + 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 sdmcRtfsCtrl( int driveno, int opcode, void* pargs) +{ + DDRIVE *pdr; + DEV_GEOMETRY gc; + int heads, secptrack; + + pdr = pc_drno_to_drive_struct( driveno); + + switch( opcode) { + case DEVCTL_GET_GEOMETRY: //formatまたはpartirionするときにRTFSが使うパラメータ + PRINTDEBUG( "DEVCTL_GET_GEOMETRY\n"); + if( (pdr->drive_flags & DRIVE_FLAGS_INSERTED) == 0) { /* 抜かれていた場合 */ + if( SDCARD_OutFlag == TRUE) { /* 今現在も抜かれているとき */ + return( -1); + }else{ /* 今現在は再挿入されているとき */ + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + } + } + + rtfs_memset( &gc, (byte)0, sizeof(gc)); + + 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] = 'C'; + gc.fmt.oemname[1] = 'T'; + gc.fmt.oemname[2] = 'R'; + 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 (pdr->drive_flags & DRIVE_FLAGS_INSERTED) { /* 抜かれてない場合 */ + 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); + } + }else{ /* 抜かれていた場合 */ + if( SDCARD_OutFlag == FALSE) { /* 排出フラグ参照 */ + pdr->drive_flags |= DRIVE_FLAGS_INSERTED; + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + PRINTDEBUG( "DEVTEST_CHANGED\n"); + return( DEVTEST_CHANGED); //挿さっている + }else{ + PRINTDEBUG( "DEVTEST_NOMEDIA\n"); + return( DEVTEST_NOMEDIA); //挿さってない + } + } + + case DEVCTL_WARMSTART: //attachのときしか呼ばれない + PRINTDEBUG( "DEVCTL_WARMSTART\n"); + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + pdr->drive_flags |= (DRIVE_FLAGS_VALID | DRIVE_FLAGS_REMOVABLE | DRIVE_FLAGS_PARTITIONED); + pdr->partition_number = 0; + + if( SDCARD_OutFlag == FALSE) { /* 排出フラグ参照 */ + pdr->drive_flags |= DRIVE_FLAGS_INSERTED; + }else{ /* カード未挿入のとき */ + pdr->drive_flags &= (~(DRIVE_FLAGS_INSERTED)); //抜かれているだけではVALIDフラグは落とさないらしい + } + 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); +} + +/*---------------------------------------------------------------------------* + 抜取コールバック関数 + + RTFSが次回"DEVCTL_GET_GEOMETRY"を行うとき、ここでセットしたパラメータを知る + *---------------------------------------------------------------------------*/ +void i_sdmcRemovedIntr( void) +{ + DDRIVE *pdr; + + pdr = pc_drno_to_drive_struct( sdmc_drive_no); + if( pdr) { + pdr->dev_table_perform_device_ioctl( pdr->driveno, + DEVCTL_REPORT_REMOVE, + (void*)0); + } + + if( func_usr_sdmc_out) { + func_usr_sdmc_out(); //ユーザコールバック + } +} + + +/*---------------------------------------------------------------------------* + Name: sdmcRtfsAttach + + Description: sdmcドライバをドライブに割り当てる + + Arguments: driveno : ドライブ番号 + + Returns: + *---------------------------------------------------------------------------*/ +BOOL sdmcRtfsAttach( int driveno) +{ + BOOLEAN result; + DDRIVE pdr; + + pdr.dev_table_drive_io = sdmcRtfsIo; + pdr.dev_table_perform_device_ioctl = sdmcRtfsCtrl; + 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, "SD"); //構造体がFSライブラリ側にコピーされる + + /*drivenoをグローバル変数に記憶*/ + sdmc_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)*/ diff --git a/build/libraries/fatfs/ARM7/firm_sdmc/sdif.c b/build/libraries/fatfs/ARM7/firm_sdmc/sdif.c new file mode 100644 index 00000000..aa770409 --- /dev/null +++ b/build/libraries/fatfs/ARM7/firm_sdmc/sdif.c @@ -0,0 +1,1188 @@ +/* + Project: CTR SD Card driver + File: sd_card.c + + 2006, Research and Development Department, Nintendo. +*/ + +#include +#include "sdmc_config.h" +#include "sdif_reg.h" /* IP 対応レジスタ定義 */ +#include +#include "sdif_ip.h" /* IP 対応フラグ定義 */ + +#if (SD_DEBUG_PRINT_ON == 1) + #if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + #define PRINTDEBUG osTPrintf + #else + #include + #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_NORMAL) { /* エラーチェック */ + 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_NORMAL) { + 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割り込み発生 + *---------------------------------------------------------------------------*/ +BOOL 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_NORMAL) { + 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; +} + + diff --git a/build/libraries/fatfs/ARM7/firm_sdmc/sdmc.c b/build/libraries/fatfs/ARM7/firm_sdmc/sdmc.c new file mode 100644 index 00000000..a5f0d897 --- /dev/null +++ b/build/libraries/fatfs/ARM7/firm_sdmc/sdmc.c @@ -0,0 +1,2683 @@ +/* + Project: CTR SD port driver + File: sdmc.c + + 2006-2007, Research and Development Department, Nintendo. +*/ + +#include +#include + +/*#if (SD_DEBUG_PRINT_ON == 1) + #if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + #define PRINTDEBUG osTPrintf + #else + #include + #define PRINTDEBUG vlink_dos_printf + #endif +#else + #define PRINTDEBUG( ...) ((void)0) +#endif*/ + +// #define PRINTDEBUG OS_TPrintf + #define PRINTDEBUG( ...) ((void)0) + + +/*********************************************************************** + 定数 +***********************************************************************/ +#define SD_STACK_SIZE (4096*2) +#define SD_THREAD_PRIO (10) +#define SD_INTR_THREAD_PRIO (SD_THREAD_PRIO - 1) + +#define SD_OPERATION_INIT (0) +#define SD_OPERATION_READ (1) +#define SD_OPERATION_READ_WITH_FIFO (2) +#define SD_OPERATION_WRITE (3) +#define SD_OPERATION_WRITE_WITH_FIFO (4) + +/* +TODO: +SD_INTR_THREAD_PRIOを高くしてSleepをなくせば動く。 +Sleepを使うには、Wakeupの前にSleepさせるためSD_INTR_THREAD_PRIOを低く +する必要があるが、Sleepの前にSD割り込みが入らなかった場合なぜかずっと +割り込みが入らなくなり動かなくなる。Sleepの前に割り込みが入れば動く。 +*/ + + +/*********************************************************************** + extern変数 +***********************************************************************/ +extern u16 BgBak[32*32]; +//u16 sdcard_request_flag; //カードからのデータ転送要求の有無フラグ +static BOOL thread_flag; + + +/*********************************************************************** + global変数 +***********************************************************************/ +BOOL sdmc_tsk_created = FALSE; +#if (TARGET_OS_CTR == 1) +ER_ID sdmc_tsk_id; //SDタスクID +ER_ID sdmc_dtq_id; +ER_ID sdmc_result_dtq_id; +ER_ID sdmc_alm_id; +ER_ID sdmc_intr_tsk_id; +#else +OSThread sdmc_tsk; +OSMessageQueue sdmc_dtq; +OSMessage sdmc_dtq_array[1]; +OSMessageQueue sdmc_result_dtq; +OSMessage sdmc_result_dtq_array[1]; +OSAlarm sdmc_alm; +OSThread sdmc_intr_tsk; +#endif + +u16 sdmc_wakeup_count = 0; //OS_WakeupThreadのキューイング代わり +u16 sdmc_intr_wakeup_count = 0; + +#if (TARGET_OS_CTR == 1) +#else +u64 sd_stack[SD_STACK_SIZE / sizeof(u64)]; +u64 sd_intr_stack[SD_STACK_SIZE / sizeof(u64)]; +#endif + +/* drsdmc.cでも参照 */ +SdmcSpec sdmc_current_spec; //TODO:ポート切り替え時、Port0とPort1に保存するように + +typedef struct { //OSMessage + void* buf; + u32 bufsize; + u32 offset; + void (*func)(void); + SdmcResultInfo* info; + u32 operation; + void (*func2)(void); +} SDCARDMsg; + + +/*********************************************************************** + static関数の宣言 +***********************************************************************/ +void i_sdmcCalcSize( void); +static void SDCARD_Backup_port0(void); +void SDCARD_Backup_port1(void); +static void SDCARD_Restore_port0(void); +void SDCARD_Restore_port1(void); + +static SDMC_ERR_CODE SDCARDi_ReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +static SDMC_ERR_CODE SDCARDi_WriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info); + +static SDMC_ERR_CODE SDCARDi_Read(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +static SDMC_ERR_CODE SDCARDi_Write(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info); + +int MMCP_SetBusWidth( BOOL b4bit); /* ビット幅の選択(MMCplus, eMMC, moviNAND) */ + +static void SDCARD_Thread( void* arg); //SDスレッド +static void SDCARD_Intr_Thread( void* arg); //SD割り込み処理スレッド + +SDMC_ERR_CODE sdmcGoIdle( void (*func1)(),void (*func2)()); +static SDMC_ERR_CODE i_sdmcInit( void); +SDMC_ERR_CODE SDCARD_Layer_Init(void); +static SDMC_ERR_CODE i_sdmcMPInit( void); /* カードドライバ初期化(マルチポート対応) */ + +static u16 i_sdmcErrProcess(void); /* エラー時の処理 */ +static u16 i_sdmcGetResid(u32 *pResid); /* 書きこみ完了セクタ数の取得 */ +static u16 i_sdmcCheckWP(void); /* SDCARD ライトプロテクトチェック */ + +static void i_sdmcEnable( void); /* SD使用のためのOS準備 */ +static void i_sdmcDisable( void); + +static u16 i_sdmcSendSCR(void); /* SCRの読み出し */ +static u16 SDCARD_SD_Status(void); /* SD_STATUSの取得 */ +static u32 SDCARD_GetR1Status(void); /* Normal response command カードステータスを取得 */ + +static void SDCARD_Dmy_Handler( void); /* 何もしない */ +static void SDCARD_Timer_irq(void* arg); /* タイムアウト割り込みハンドラ */ +static void SDCARD_irq_Handler( void); /* SD-IPからの割り込みハンドラ */ +static void SDCARD_FPGA_irq(void); /* カードリードライト割り込み処理 */ +static void SDCARD_ATC0_irq(void); /* ATC0転送完了割り込み処理 */ +static void SYSFPGA_irq(void); /* SYSFPGAエラー割り込み処理 */ + +/*ポート1は無線固定なのでポート選択関数は公開しない*/ +static u16 i_sdmcSelectedNo(void); /* カードポートの選択 */ +static u16 i_sdmcSelect(u16 select); /* 現在のカードポート番号のチェック */ + + + + +/*********************************************************************** + 外部参照変数 +***********************************************************************/ +static void SDCARD_TimerStart(u32 tim); /* タイムアウト計測スタート */ +void SDCARD_TimerStop(void); /* タイムアウト計測停止 */ + +extern u16 SD_CID[8]; /* CID値保存用 */ +extern u16 SD_CSD[8]; /* CSD値保存用 */ +extern u16 SD_OCR[2]; /* OCR値保存用 */ +extern u16 SD_SCR[4]; /* SCR値保存用 */ +extern u16 SD_RCA; /* RCA値保存用 */ + +extern s16 SDCARD_MMCFlag; /* MMCカードフラグ */ +extern s16 SDCARD_SDHCFlag; /* SDHCカードフラグ */ +extern u16 SD_port_number; /* 現在ポート番号 */ + +//static BOOL init_io_exist; /* SDIO存在フラグ */ +//static BOOL init_mem_exist; /* メモリ存在フラグ */ + + +/*********************************************************************** + グローバル +***********************************************************************/ +u16 SD_SDSTATUS[32]; /* SD_STATUSレジスタ保存用 */ +u16 SDCARD_WP_FLAG0; /* カードライトプロテクトフラグ。0=なし、1=有り */ +u16 SDCARD_WP_FLAG1; /* カードライトプロテクトフラグ。0=なし、1=有り */ +u16 SDCARD_WP_PERMANENT; /* カードライトプロテクト永久フラグ。0=なし、1=有り */ +u16 SDCARD_WP_TEMPORARY; /* カードライトプロテクト一時フラグ。0=なし、1=有り */ + +u16* pSDCARD_BufferAddr; /* 保存用データ格納バッファアドレス */ + +u32 ulSDCARD_SectorCount; /* 転送セクタ数 */ +u32 ulSDCARD_RestSectorCount; /* 残り転送セクタ数 */ +u32 SDCARD_SectorSize; /* セクタサイズ デフォルト 512bytes */ + +u16 SD_INFO1_VALUE; /* SD_INFO1レジスタ取得用変数 */ +u16 SD_INFO1_MASK_VALUE; /* SD_INFO1割込みマスク用変数(0で許可, 1で禁止) */ +u16 SD_INFO2_VALUE; /* SD_INFO2レジスタ取得用変数 */ +u16 SD_INFO2_MASK_VALUE; /* SD_INFO2割り込みマスク用変数(0で許可, 1で禁止) */ +u16 SD_INFO_ERROR_VALUE; /* SD_INFO2, SD_INFO1のエラービット確認用変数 */ + +u16 SD_port_en_numbers; /* サポートするポート数 */ + + + +/*ポート状態保存*/ +SDPortContext SDPort0Context; +SDPortContext SDPort1Context; +//SDPortContext *SDPortCurrentContext = &SDPort0Context; /*TODO*/ + + + +u16 TransCount; /* R/W転送カウント変数 */ + +u32 ulSDCARD_Size; /* カード全セクタ数 */ + +volatile s16 SDCARD_ATC0_Flag; /* 全ATC完了フラグ */ +volatile s16 SDCARD_FPGA_Flag; /* FPGA処理完了フラグ */ +volatile s16 SDCARD_EndFlag; /* 転送処理完了フラグ */ + +SDMC_ERR_CODE SDCARD_ErrStatus; /* エラーステータス */ +vu32 SDCARD_Status; /* カードステータス */ +s16 SDCARD_SDFlag; /* SDカードフラグ */ + +volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ +SdmcResultInfo *pSDCARD_info; /* 保存用実行結果構造体ポインタ */ + +u16 SDCARD_IO_Port; /* カード挿入/排出割り込み発生時のポート番号 */ + +void (*func_SDCARD_In)(void); /* カード挿入イベント用コールバック保存用 */ +void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */ +/* void (*func_SDCARD_CallBack)(SdmcResultInfo *info); 処理結果通知用コールバック保存用 */ + + + +extern SDMC_ERR_CODE i_sdmcMPInitFirm( void); + + +/*---------------------------------------------------------------------------* + Name: SDCARD_Backup_port0 + + Description: backup registers and variables of port0. + ポート0のレジスタや変数をバックアップする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Backup_port0(void) +{ + /* registers */ + SD_GetFPGA(SDPort0Context.SD_CLK_CTRL_VALUE,SD_CLK_CTRL); + SD_GetFPGA(SDPort0Context.SD_OPTION_VALUE, SD_OPTION); + + /* variables */ + SDPort0Context.SD_RCA = SD_RCA; + SDPort0Context.ErrStatus = SDCARD_ErrStatus; + SDPort0Context.Status = SDCARD_Status; + SDPort0Context.MMCFlag = SDCARD_MMCFlag; + SDPort0Context.SDHCFlag = SDCARD_SDHCFlag; + SDPort0Context.SDFlag = SDCARD_SDFlag; + + SDPort0Context.OutFlag = SDCARD_OutFlag; + + /*media registers*/ + MI_CpuCopy8( SD_CID, SDPort0Context.SD_CID, 16); + MI_CpuCopy8( SD_CSD, SDPort0Context.SD_CSD, 16); + MI_CpuCopy8( SD_OCR, SDPort0Context.SD_OCR, 4); + MI_CpuCopy8( SD_SCR, SDPort0Context.SD_SCR, 8); +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Backup_port1 + + Description: backup registers and variables of port1. + ポート1のレジスタや変数をバックアップする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_Backup_port1(void) +{ + /* registers */ + SD_GetFPGA(SDPort1Context.SD_CLK_CTRL_VALUE,SD_CLK_CTRL); + SD_GetFPGA(SDPort1Context.SD_OPTION_VALUE, SD_OPTION); + + /* variables */ + SDPort1Context.SD_RCA = SD_RCA; + SDPort1Context.ErrStatus = SDCARD_ErrStatus; + SDPort1Context.Status = SDCARD_Status; + SDPort1Context.MMCFlag = SDCARD_MMCFlag; + SDPort1Context.SDHCFlag = SDCARD_SDHCFlag; + SDPort1Context.SDFlag = SDCARD_SDFlag; + + SDPort1Context.OutFlag = SDCARD_OutFlag; + + /*media registers*/ + MI_CpuCopy8( SD_CID, SDPort1Context.SD_CID, 16); + MI_CpuCopy8( SD_CSD, SDPort1Context.SD_CSD, 16); + MI_CpuCopy8( SD_OCR, SDPort1Context.SD_OCR, 4); + MI_CpuCopy8( SD_SCR, SDPort1Context.SD_SCR, 8); +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcEnable + + Description: assign OS resouce for using SD memory card. + SDカードを使うための準備をする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void i_sdmcEnable( void) +{ +#if (TARGET_OS_CTR == 1) + /*SD interrupt setting*/ +// osInitIntrFlag(); +// osClearInterruptPendingID( OS_INTR_ID_SD); +// *(vu32*)CTR_INT_IF = CTR_IE_SD_MASK; + osSetInterruptHandler( OS_INTR_ID_SD, SDCARD_irq_Handler); + osEnableInterruptID( OS_INTR_ID_SD); +// *(vu32*)CTR_INT_SE = CTR_IE_SD_MASK; //割り込み(IRQ)発生許可 +// *(vu32*)CTR_INT_IE = CTR_IE_SD_MASK; +// osEnableInterrupts(); +// *(vu16*)0x04000208 = 1; +#else + /*SD割り込みのIF解除*/ +// *SDIF_CNT_L = (SDIF_CNT_FCLR | SDIF_CNT_USEFIFO); //ラッパーレジスタ(sdmcReset呼ぶならいらない) +// SD_AndFPGA( SD_OPTION, SD_CD_DETECT_TIME); /* CD 検出タイムをゼロクリア(sdmcReset呼ぶならいらない) */ + + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; + OS_SetIrqFunction( OS_IE_SD1, SDCARD_irq_Handler); + OS_EnableIrqMask( OS_IE_SD1); +#endif +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcDisable + + Description: under construction + 工事中 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void i_sdmcDisable( void) +{ +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_irq_Handler + + Description: SD interrupt handler + SD割り込みハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_irq_Handler( void) +{ +#if (TARGET_OS_CTR == 1) + iwup_tsk( sdmc_intr_tsk_id); +#else + PRINTDEBUG( "SD irq!\n"); +// OS_DumpThreadList(); + OS_SetIrqCheckFlag( OS_IE_SD1); +// sdmc_intr_wakeup_count++; +// OS_WakeupThreadDirect( &sdmc_intr_tsk); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Dmy_Handler + + Description: dmy handler for timer interrupt. + タイマー割り込み用ダミーハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Dmy_Handler( void) +{ +} + +/*---------------------------------------------------------------------------* + Name: sdmcInit + + Description: Initialize SD interface and SD card. + 初期化 + + Arguments: dma_no : DMA番号 + func1 : カード挿入時コールバック関数 + func2 : カード排出時コールバック関数 + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcInit( SDMC_DMA_NO dma_no, void (*func1)(),void (*func2)()) +{ +#if (TARGET_OS_CTR == 1) + T_CALM calm; + T_CTSK ctsk; + T_CDTQ cdtq; +#endif +// SDCARDMsg SdMsg; +// u32 init_msg; + SDMC_ERR_CODE api_result; + + if( sdmc_tsk_created == FALSE) { + /*---------- OS準備 ----------*/ + /* アラームハンドラ登録 */ +#if (TARGET_OS_CTR == 1) + calm.almatr = TA_HLNG; // set attribution : for high level language + calm.exinf = 0; // set argument for alarm handler + calm.almhdr = SDCARD_Timer_irq; // set alarm handler + sdmc_alm_id = acre_alm(&calm); + if (sdmc_alm_id < 0) + { + PRINTDEBUG("create_alarm_simple: Cannot create new alarm handler (%d).\n", sdmc_alm_id); + } + + /* メッセージ初期化 */ + // setup dataqueue structure + cdtq.dtqatr = TA_TFIFO; // set attribution : normal FIFO + cdtq.dtqcnt = 1; // there are 2 datas in queue + cdtq.dtq = NULL; // set data queue address : NULL means automatically allocated by kernel + sdmc_dtq_id = acre_dtq(&cdtq); + if (sdmc_dtq_id < 0) + { + PRINTDEBUG("create_dataqueue_simple: Cannot create new data queue.\n"); + } + /**/ + cdtq.dtqatr = TA_TFIFO; // set attribution : normal FIFO + cdtq.dtqcnt = 1; // there are 2 datas in queue + cdtq.dtq = NULL; // set data queue address : NULL means automatically allocated by kernel + sdmc_result_dtq_id = acre_dtq(&cdtq); + if (sdmc_result_dtq_id < 0) + { + PRINTDEBUG("create_dataqueue_simple: Cannot create new data queue.\n"); + } + +// OS_InitThread(); //自分の優先度が16になる +// chg_pri( (ID)0, (PRI)12); + + /* SDタスクの立ち上げ */ + ctsk.tskatr = TA_HLNG | TA_ACT; // set attribution : for high level language and running now + ctsk.task = SDCARD_Thread; // set task routine + ctsk.exinf = (void*)0; // set argument for task routine + ctsk.itskpri = SD_THREAD_PRIO; // set priority + ctsk.stksz = SD_STACK_SIZE; // set stack size + ctsk.stk = NULL; // set stack address : NULL means automatically allocated by kernel + sdmc_tsk_id = acre_tsk(&ctsk); + if (sdmc_tsk_id < 0) + { + PRINTDEBUG("create_task_sd: Cannot create new task.\n"); + }else{ + if( (sdmc_tsk_id == E_NOID)||(sdmc_tsk_id == E_NOMEM)||(sdmc_tsk_id == E_RSATR)|| + (sdmc_tsk_id == E_PAR)||(sdmc_tsk_id == E_OBJ)) { + PRINTDEBUG("create_task_sd: Cannot create new task.\n"); + } + PRINTDEBUG("create_task_sd: 0x%x\n", sdmc_tsk_id); + } + /*----------------------------*/ + + /* SD割り込み処理タスクの立ち上げ */ + ctsk.tskatr = TA_HLNG | TA_ACT; // set attribution : for high level language and running now + ctsk.task = SDCARD_Intr_Thread; // set task routine + ctsk.exinf = (void*)0; // set argument for task routine + ctsk.itskpri = SD_INTR_THREAD_PRIO; // set priority + ctsk.stksz = SD_STACK_SIZE; // set stack size + ctsk.stk = NULL; // set stack address : NULL means automatically allocated by kernel + sdmc_intr_tsk_id = acre_tsk(&ctsk); + if (sdmc_intr_tsk_id < 0) + { + PRINTDEBUG("create_intr_task_sd: Cannot create new task.\n"); + }else{ + if( (sdmc_intr_tsk_id == E_NOID)||(sdmc_intr_tsk_id == E_NOMEM)||(sdmc_intr_tsk_id == E_RSATR)|| + (sdmc_intr_tsk_id == E_PAR)||(sdmc_intr_tsk_id == E_OBJ)) { + PRINTDEBUG("create_intr_task_sd: Cannot create new task.\n"); + } + PRINTDEBUG("create_intr_task_sd: 0x%x\n", sdmc_intr_tsk_id); + } + +#else //(TARGET_OS_NITRO = 1) + /*---------- OS準備 ----------*/ + if( !OS_IsAlarmAvailable()) { /* アラームチェック(OS_InitAlarm済みか?) */ + SDCARD_ErrStatus |= SDMC_ERR_END; + }else{ + OS_CreateAlarm( &sdmc_alm); //使用可能であれば初期化 + } + + /* メッセージ初期化 */ + OS_InitMessageQueue( &sdmc_dtq, &sdmc_dtq_array[0], 1); + OS_InitMessageQueue( &sdmc_result_dtq, &sdmc_result_dtq_array[0], 1); + +// OS_InitThread(); //自分の優先度が16になる + + /* SDスレッドの立ち上げ */ + OS_CreateThread( &sdmc_tsk, SDCARD_Thread, NULL, + (sd_stack+SD_STACK_SIZE / sizeof(u64)), SD_STACK_SIZE, SD_THREAD_PRIO); + OS_WakeupThreadDirect( &sdmc_tsk); + PRINTDEBUG( "sdmc_tsk:0x%x\n", &sdmc_tsk); + + + /* SD割り込み処理スレッドの立ち上げ */ + (void)OS_ClearIrqCheckFlag( OS_IE_SD1); + OS_CreateThread( &sdmc_intr_tsk, SDCARD_Intr_Thread, NULL, + (sd_intr_stack+SD_STACK_SIZE / sizeof(u64)), SD_STACK_SIZE, SD_INTR_THREAD_PRIO); + OS_WakeupThreadDirect( &sdmc_intr_tsk); + PRINTDEBUG( "sdmc_intr_tsk:0x%x\n", &sdmc_intr_tsk); + /*----------------------------*/ +#endif + /**/ + sdmc_tsk_created = TRUE; + } + + /**/ + func_SDCARD_In = func1; /* カード挿入イベント用関数のアドレスを設定 */ + func_SDCARD_Out = func2; /* カード排出イベント用関数のアドレスを設定 */ + api_result = sdmcGoIdle( func1, func2); +// api_result = SDMC_NORMAL; + + return api_result; +} + +/* カードが入れ換わったときなどに初期化(RTFS用)*/ +SDMC_ERR_CODE sdmcGoIdle( void (*func1)(),void (*func2)()) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 init_msg; +#else + OSMessage init_msg; +#endif + SDMC_ERR_CODE api_result; + + func_SDCARD_In = func1; /* カード挿入イベント用関数のアドレスを設定 */ + func_SDCARD_Out = func2; /* カード排出イベント用関数のアドレスを設定 */ + + /*----- SDスレッドと通信 -----*/ +#if (TARGET_OS_CTR == 1) + SdMsg.operation = SD_OPERATION_INIT; + + snd_dtq( sdmc_dtq_id, (VP_INT)&SdMsg); + + /* 返り値待ち */ + rcv_dtq( sdmc_result_dtq_id, (VP_INT*)&init_msg); + api_result = (SDMC_ERR_CODE)init_msg; +#else + SdMsg.operation = SD_OPERATION_INIT; +// SdMsg.func = func1; +// SdMsg.func2 = func2; + + init_msg = (OSMessage)&SdMsg; + OS_SendMessage( &sdmc_dtq, init_msg, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ + OS_ReceiveMessage( &sdmc_result_dtq, &init_msg, OS_MESSAGE_BLOCK); + api_result = (SDMC_ERR_CODE)init_msg; +#endif + /*----------------------------------*/ + + return api_result; +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcInit + + Description: Initialize SD interface and SD card. + 初期化 + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcInit( void) +{ + i_sdmcEnable(); + + /* SD初期化 */ + SDCARD_ErrStatus = sdmcReset(); + + if(!SDCARD_ErrStatus) { + SDCARD_ErrStatus = i_sdmcMPInitFirm(); + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: sdmcReset + + Description: reset SD card. + リセット + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReset( void) +{ + OSIntrMode irq_core_flag; + ulSDCARD_Size = 0; /* カード全セクタ数クリア */ + SDCARD_MMCFlag = FALSE; /* MMCカード判定フラグクリア */ + SDCARD_SDHCFlag = FALSE; + SDCARD_SDFlag = FALSE; /* SDカード判定フラグクリア */ + + /*** カードステータスをクリア ***/ + SDCARD_ErrStatus = SDMC_NORMAL; + SDCARD_Status = SDMC_NORMAL; + + /*** カードCSD WPビットをクリア ***/ + SDCARD_WP_FLAG0 = 0; + SDCARD_WP_FLAG1 = 0; + SDCARD_WP_PERMANENT = 0; + SDCARD_WP_TEMPORARY = 0; + + pSDCARD_info = NULL; + SDCARD_OutFlag = FALSE; /* カード排出発生判定フラグクリア */ + +#if (TARGET_OS_CTR == 1) + irq_core_flag = osDisableInterrupts(); /* 割込み禁止 */ +#else + irq_core_flag = OS_DisableInterrupts(); /* 割込み禁止 */ +#endif + *SDIF_CNT_L = (SDIF_CNT_FCLR | SDIF_CNT_USEFIFO); //ラッパーレジスタ + *SDIF_CNT_L = 0x0000; //ラッパーレジスタ + *SDIF_FDS_L = 0; + *SDIF_FSC_L = 1; + SD_Init(); /* SD Card I/F 初期化処理 */ + SD_AndFPGA( SD_OPTION, SD_CD_DETECT_TIME); /* CD 検出タイムをゼロクリア */ + + SD_port_en_numbers = SDCARD_PORT_NO_MAX; /*** サポートするポート数をデフォルトに設定 ***/ + SD_port_number = 0; /*** 現在のポート番号をデフォルトに設定 ***/ + + SDCARD_Backup_port0(); /* port0 backup */ + SDCARD_Backup_port1(); /* port1 backup */ + +#if (TARGET_OS_CTR == 1) + osRestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#else + OS_RestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#endif + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Layer_Init + + Description: initialize sequence for SD card. + SDカード規定の初期化手順 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE SDCARD_Layer_Init(void) +{ +// SYSTIM wait_tim, limit_tim; + +// u16 memory_exist, function_number; + SDCARD_Status = SDMC_NORMAL; /* カードステータスをクリア */ +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + SDCARD_MMCFlag = FALSE; /* MMCカード判定フラグクリア */ + SDCARD_SDHCFlag = FALSE; + SDCARD_SDFlag = FALSE; /* SDカード判定フラグクリア */ + SDCARD_OutFlag = FALSE; /* カード排出発生判定フラグクリア */ + ulSDCARD_Size = 0; /* カード全セクタ数クリア */ + TransCount = 0; /* 転送カウント変数クリア */ +// init_io_exist = 0; +// init_mem_exist = 0; + + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_128)); /* SDクロックの周波数 261KHz(初期化時は100〜400khz) */ + SD_EnableClock(); /* SDカードのクロックをイネーブルにする */ + + /* SD I/F部ダミー80クロック(1mSec)転送待ち(タイマーで待ちを実装しても良い) */ +#if (TARGET_OS_CTR == 1) + dly_tsk( 1); +#else +// OS_Sleep( 1); + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us +#endif + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RESET_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + PRINTDEBUG( " CMD0(GO_IDLE_STATE)\n"); + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウト以外のエラーをクリア */ + { +/*PRINTDEBUG( "SD_INFO1 : 0x%x\n", SD_INFO1); +PRINTDEBUG( "SD_INFO2 : 0x%x\n", SD_INFO2); +PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", SD_INFO1_MASK); +PRINTDEBUG( "SD_INFO2_MASK : 0x%x\n", SD_INFO2_MASK); +PRINTDEBUG( "SD_CLK_CTRL : 0x%x\n", SD_CLK_CTRL); +PRINTDEBUG( "SD_SIZE : 0x%x\n", SD_SIZE); + +PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20)));*/ + } + SD_Command(SD_CMD_CMD | GO_IDLE_STATE); /* CMD0発行、レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /*------- idle state -------*/ +#if (TARGET_OS_CTR == 1) + dly_tsk( 1); /* 1ms待ち */ +#else +// OS_Sleep( 1); + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us +#endif + SD_SendIfCond(); /* CMD8発行、レスポンス確認 */ + if( !SDCARD_SDHCFlag) { /* SDHC以外は失敗してるはずなので */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーフラグをクリアしておく */ + } //注:CMD8によりここで割り込みが入る! + + while(!(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT)){ /* タイムアウトになったら抜ける */ + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); + + SD_RCA = 0; /* RCA = 0をセット */ + if(!SDCARD_MMCFlag){ /* MMCカードフラグが 0(OFF) か? */ + if(!SD_AppCommand()){ /* CMD55 発行処理が正常か? */ + SDCARD_MMCFlag = FALSE; /* MMCカードフラグクリア */ + if(!SD_AppOpCond()){ /* ACMD41発行処理が正常か?(OCR31bit = L の時 No Response) */ + SDCARD_SDFlag = TRUE; /* SDカードフラグセット */ + break; + } + }else{ /* CMD55 が正常終了しない */ + if(SDCARD_ErrStatus == SDMC_ERR_TIMEOUT){ /* タイムアウト(==No Response)か? */ + SDCARD_MMCFlag = TRUE; /* MMCカードフラグセット */ + }else{ +// break; //コメントアウトしないとSDカードの初期化に失敗する + } + } + } + if(SDCARD_MMCFlag){ /* MMCカードフラグが 1(ON) のとき */ + SD_RCA = 1; /* RCA = 1をセット */ + if(!SD_SendOpCond()){ /* CMD1発行処理が正常か? */ + break; + } + } + } +/* + if( SDCARD_SDHCFlag) { + SD_ReadOCR(); + } +*/ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーかチェック */ + SD_ClrErr(SDMC_ERR_FPGA_TIMEOUT); /* タイムアウトエラーの設定クリア */ + SD_SetErr(SDMC_ERR_RESET); /* 初期化カードリセットコマンド時1.5秒タイムアウトエラーの設定 */ + } + SDCARD_MMCFlag = FALSE; /* MMCカードフラグクリア */ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_INITIAL_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + SD_SendCID(); /* CMD2発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + while(1){ + SD_SendRelativeAddr(); /* CMD3発行 レスポンス確認 正常終了時 RCA<-ResのRCA */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + if(SD_RCA != 0){ + break; + } + } + /*------- standby state -------*/ + SD_SendCSD(); /* CMD9発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); + + /* 転送速度設定 */ + SD_ClockDivSet(SD_RSP5); /* SDカードの動作クロック設定 (CSD[5]) */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + /* Command toggles acard between the Stand-by and Transfer states */ + SD_SelectCard(); /* CMD7発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /*------- translate state -------*/ + + SDCARD_SectorSize = SECTOR_SIZE; /* セクタサイズ デフォルト 512bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* CMD16 ブロックサイズの設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + +#if SCR_ON + SD_SelectBitWidth(FALSE); /* CMD55->ACMD6 ビット幅の選択 1bit */ + + /* ACMD51 発行 SD configuration register (SCR) */ + if(SDCARD_SDFlag){ /* SDカードフラグ ON かチェック */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + i_sdmcSendSCR(); + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } +#if TIMEOUT + SDCARD_TimerStart(SDCARD_CLOCK_WAIT);/* タイムアウト判定用タイマスタート */ +#endif + } +#endif + SD_EnableClock(); /* SD-CLK Enable */ + + if(SDCARD_MMCFlag){ /* MMCカード ON かチェック */ + if( ((SD_CSD[7] & 0x3C)>>2) >= 4) { + MMCP_SetBusWidth( TRUE); + } +// SD_SelectBitWidth(FALSE); /* CMD55->ACMD6 ビット幅の選択 1bit */ + }else{ + SD_SelectBitWidth(TRUE); /* CMD55->ACMD6 ビット幅の選択 4bit */ + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + + if(SDCARD_SDFlag){ /* SDカードフラグ ON かチェック */ + if (SDCARD_SD_Status()) /* CMD55->ACMD13 カードステータスを取得 */ + return SDCARD_ErrStatus; + if(SD_SDSTATUS[1] & SD_MEMORY_CARD){ + SDCARD_SDFlag = FALSE; /* SDカードフラグクリア */ + } + } + + i_sdmcCalcSize(); + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcCalcSize + + Description: + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +void i_sdmcCalcSize( void) +{ + u32 ulCSize; + u16 read_block_len_val, mult_val; + + /*--------------カードサイズの算出---------------*/ + if( ((SD_CSD[7] & CSD_STRUCT_BIT_127_126) >> 6) == 0x1) { //SDHCのとき + sdmc_current_spec.csd_ver2_flag = 1; + ulCSize = (u32)((((u32)(SD_CSD[3]) & CSD_C_SIZE_BIT_69_56) << 8) + + ((SD_CSD[2] & CSD_C_SIZE_BIT_55_48) >> 8) + 1); + ulCSize = ulCSize * 1024; //もともと512KByte単位なのを512Byte単位にする + /* データ領域サイズ算出 */ + sdmc_current_spec.memory_capacity = ulCSize; + ulSDCARD_Size = ulCSize; + /* プロテクト領域サイズ算出 */ + sdmc_current_spec.protected_capacity = (((SD_SwapByte( &SD_SDSTATUS[2])) << 16) + + (SD_SwapByte( &SD_SDSTATUS[3]))) / 0x200; + /*トータルサイズ算出 */ + sdmc_current_spec.card_capacity = sdmc_current_spec.memory_capacity + + sdmc_current_spec.protected_capacity; + + }else{ //従来SDカードのとき + sdmc_current_spec.csd_ver2_flag = 0; + ulCSize = (u32)(((SD_CSD[3] & CSD_C_SIZE_BIT_71_62) >> 6) + + ((SD_CSD[4] & CSD_C_SIZE_BIT_73_72) << 10) + 1); + mult_val = ((SD_CSD[2] & CSD_C_SIZE_MULT) >> 7) + 2; //2の乗数 + ulCSize = ulCSize << mult_val; + if(SDCARD_MMCFlag){ /* MMCカードフラグON かチェック */ + read_block_len_val = ((SD_CSD[4] & CSD_READ_BL_LEN) >> 8); + ulCSize = (ulCSize << read_block_len_val); + }else{ /* SDカードフラグ(SDCARD_SDFlag)ON のはず */ + read_block_len_val = (((SD_CSD[1] & CSD_WRITE_BL_LEN_BIT_25_24) << 2) | + ((SD_CSD[0] & CSD_WRITE_BL_LEN_BIT_23_22) >> 14)); + ulCSize = (ulCSize << read_block_len_val); + } + /* データ領域サイズ算出 */ + ulCSize /= SDCARD_SectorSize; /* 全セクタ数の算出 */ + sdmc_current_spec.memory_capacity = ulCSize; + ulSDCARD_Size += ulCSize; /* 全セクタ数のセット */ + /* プロテクト領域サイズ算出 */ + sdmc_current_spec.protected_capacity = ((SD_SwapByte( &SD_SDSTATUS[2])) << 16) + + (SD_SwapByte( &SD_SDSTATUS[3])); + sdmc_current_spec.protected_capacity <<= mult_val; + sdmc_current_spec.protected_capacity <<= read_block_len_val; + sdmc_current_spec.protected_capacity /= SDCARD_SectorSize; //TODO:構造体にまとめること + /*トータルサイズ算出 */ + sdmc_current_spec.card_capacity = sdmc_current_spec.memory_capacity + + sdmc_current_spec.protected_capacity; + } + sdmc_current_spec.SS = SDCARD_SectorSize; + + PRINTDEBUG( "SD memory capacity : 0x%x\n", sdmc_current_spec.memory_capacity); + PRINTDEBUG( "SD protected capacity : 0x%x\n", sdmc_current_spec.protected_capacity); + PRINTDEBUG( "SD total capacity : 0x%x\n", sdmc_current_spec.card_capacity); +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcMPInit + + Description: initialize SD card in multi ports. + マルチポートのSDカード初期化 + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcMPInit( void) +{ + if(((SD_port_number == SDCARD_PORT0) && (!SD_CheckFPGAReg(SD_INFO1,SD_INFO1_DETECT))) || + ((SD_port_number == SDCARD_PORT1) && (!SD_CheckFPGAReg(EXT_CD,EXT_CD_PORT1_DETECT))) || + (SD_port_number > SDCARD_PORT1)) + { + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + SDCARD_OutFlag = TRUE; /* 排出フラグをセット */ + }else{ + if( SD_CheckFPGAReg( SD_INFO1, SD_INFO1_DETECT)) { + sdmcSelect( (u16)SDMC_PORT_CARD); + SDCARD_ErrStatus = SDCARD_Layer_Init(); + } + if( SD_CheckFPGAReg( EXT_CD, EXT_CD_PORT1_DETECT)) { + sdmcSelect( (u16)SDMC_PORT_NAND); + SDCARD_ErrStatus = SDCARD_Layer_Init(); + } + SDCARD_OutFlag = FALSE; /* 排出フラグをリセット */ + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + SD_DisableClock(); /* SD-CLK Disable */ + SD_EnableInfo(); /* SD Card 挿抜 割り込み許可 */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcGetStatus + + Description: get card status + カードの状態を取得する + bit15 SDカード判別ビット(検出したら1) + bit14 MMCカード判別ビット(検出したら1) + bit10 IO3 card detect(検出したら1) ※CTRではプルアップのため使えない + bit9 IO3 card inserted(挿入動作で1) ※CTRではプルアップのため使えない + bit8 IO3 card removed(脱動作で1) ※CTRではプルアップのため使えない + bit7 write protect(書き込み禁止の場合1) + bit5 card detect(検出したら1) + bit4 card inserted(挿入動作で1) + bit3 card removed(脱動作で1) + bit2 R/W access all end + bit0 Response end + + Arguments: *status : カードの状態を格納する変数へのポインタ + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +/*----------------------------------------------- +SD_INFO1レジスタ +bit[10,9,8,7] = DAT3CD, DAT3IN, DAT3OUT, WP +bit[5, 4, 3, 2] = CD, INS, REM, ALLEND +bit0 = RESEND +------------------------------------------------- +EXT_CDレジスタ +bit[2,1,0] = P1CD, P1INS, P1REM +------------------------------------------------- +EXT_CD_DAT3レジスタ +bit[2, 1, 0] = P1DCD, P1DINS, P1DREM +------------------------------------------------- +EXT_WPレジスタ +bit0 = P1WP +-----------------------------------------------*/ +SDMC_ERR_CODE sdmcGetStatus(u16 *status) +{ + u16 SD_INFO1_STATUS; + + SD_INFO1_STATUS = SD_INFO1; /* SD_INFO1レジスタ読み出し */ + *status = SD_INFO1_STATUS; /* 論理反転 */ + + /*--- ポート0のとき ---*/ + if(SD_port_number == SDCARD_PORT0) + { + *status &= SDCARD_FLAG_CLR; /* SD/MMCフラグクリア */ + } + /*--- ポート1のとき ---*/ + else if (SD_port_number == SDCARD_PORT1) + { + *status &= SDCARD_PORT1_CLR; /* port1に関係ない部分をクリア */ + SD_INFO1_STATUS = (u16)((EXT_CD & 0x0007) << 3); + SD_INFO1_STATUS |= ((EXT_CD_DAT3 & 0x0007) << 8); + SD_INFO1_STATUS |= ((EXT_WP & 0x0001) << 7); + *status |= SD_INFO1_STATUS; /* カードport1フラグ設定 */ + } + /*--- SD/MMCフラグをセット ---*/ + if( SDCARD_MMCFlag) { /* 検出したカードがMMCカードの時 */ + *status |= SDCARD_FLAG_MMC; /* カード判定部分MMCカード */ + } + if( SDCARD_SDFlag) { /* 検出したカードがSDカードの時 */ + *status |= SDCARD_FLAG_SD; /* カード判定部分SDカード */ + } + + return SDMC_NORMAL; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_GetR1Status + + Description: get the card status of R1 response. + R1レスポンスのカードステータスを取得する。 + + Arguments: None + + Returns: SDCARD_Status : R1の[39:8] + *---------------------------------------------------------------------------*/ +static u32 SDCARD_GetR1Status(void) +{ + /* SD_CheckStatusでSDCARD_Statusに値が入る */ + return SDCARD_Status; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcReadFifo + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 recv_dat; +#else + OSMessage recv_dat; +#endif + SDMC_ERR_CODE api_result; //SDCARD関数の返り値 + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ_WITH_FIFO; + +#if (TARGET_OS_CTR == 1) + PRINTDEBUG( "readfifo : snd_dtq begin\n"); + snd_dtq( sdmc_dtq_id, (VP_INT)&SdMsg); + + /* 返り値待ち */ + PRINTDEBUG( "readfifo : rcv_dtq begin\n"); + rcv_dtq( sdmc_result_dtq_id, (VP_INT*)&recv_dat); + + api_result = (SDMC_ERR_CODE)recv_dat; +#else + recv_dat = (OSMessage)&SdMsg; //SdMsgのアドレスを伝える + OS_SendMessage( &sdmc_dtq, recv_dat, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ + OS_ReceiveMessage( &sdmc_result_dtq, &recv_dat, OS_MESSAGE_BLOCK); + api_result = (SDMC_ERR_CODE)recv_dat; +#endif + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_ReadFifo + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_ReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDMC_ERR_CODE result; + + /* FIFO Empty割り込み無効、FIFO Full割り込み有効 */ + *(SDIF_CNT) = (*(SDIF_CNT) & (~SDIF_CNT_FEIE)) | SDIF_CNT_FFIE; + *(SDIF_FDS) = (u16)SDCARD_SectorSize; /* FIFOのデータサイズ */ + *(SDIF_FSC) = bufsize; + *(SDIF_CNT) |= (SDIF_CNT_USEFIFO | SDIF_CNT_FCLR); /* FIFO使用フラグON */ + CC_EXT_MODE = CC_EXT_MODE_DMA; /* DMAモードON */ + + result = SDCARDi_Read( buf, bufsize, offset, func, info); + + /* FIFO無効に */ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* FIFO使用フラグOFF */ + CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */ + + return result; +} + +/*---------------------------------------------------------------------------* + Name: sdmcRead + + Description: read from card. + カードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcRead(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 recv_dat; +#else + OSMessage recv_dat; +#endif + SDMC_ERR_CODE api_result; + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ; + +#if (TARGET_OS_CTR == 1) + snd_dtq( sdmc_dtq_id, (VP_INT)&SdMsg); + + /* 返り値待ち */ + rcv_dtq( sdmc_result_dtq_id, (VP_INT*)&recv_dat); + + api_result = (SDMC_ERR_CODE)recv_dat; +#else + recv_dat = (OSMessage)&SdMsg; + OS_SendMessage( &sdmc_dtq, recv_dat, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ + OS_ReceiveMessage( &sdmc_result_dtq, &recv_dat, OS_MESSAGE_BLOCK); + api_result = (SDMC_ERR_CODE)recv_dat; +#endif + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_Read + + Description: read from card. + カードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_Read(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + s16 nRetryCount; /* リトライ回数カウント */ + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + + for( nRetryCount=0; nRetryCountresult = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + } + }else{ /*--- 残りセクタ数が 0 でないとき ---*/ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + } +} + +/*---------------------------------------------------------------------------* + Name: SYSFPGA_irq + + Description: insert/remove/error/access end interrupt handler. + BREやBWE割り込みを除く割り込みのハンドラ。挿抜、エラー発生、 + アクセス終了の割り込み発生時にそれぞれの処理を行う。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SYSFPGA_irq(void) +{ + /*--- ポート0の挿抜割り込みチェックとコールバック起動 ---*/ + if(!SD_CheckFPGAReg( SD_INFO1_MASK, SD_INFO1_MASK_REMOVE)){ /* SD Card 抜け 割込み許可状態か? */ + if( SD_CheckFPGAReg( SD_INFO1, SD_INFO1_REMOVE)){ /* SD Card 抜け 発生か? */ + SD_AndFPGA( SD_INFO1,(~SD_INFO1_REMOVE)); /* INFO1の抜けフラグを落とす */ + SDCARD_OutFlag = TRUE; /* 排出フラグセット */ + if(func_SDCARD_Out){ /* コールバック関数のNullチェック */ + SDCARD_IO_Port = SDCARD_PORT0; /* カード抜けポート番号を設定 */ + func_SDCARD_Out(); /* カード抜けコールバック関数呼び出し */ + } + } + } + if(!SD_CheckFPGAReg( SD_INFO1_MASK, SD_INFO1_MASK_INSERT)){ /* SD Card 挿入 割込み許可状態か? */ + if( SD_CheckFPGAReg( SD_INFO1, SD_INFO1_INSERT)){ /* SD Card 挿入 発生か? */ + SD_AndFPGA( SD_INFO1, (~SD_INFO1_INSERT)); /* INFO1の挿入フラグを落とす */ + SDCARD_OutFlag = FALSE; /* 排出フラグリセット */ + if(func_SDCARD_In){ /* コールバック関数のNullチェック */ + SDCARD_IO_Port = SDCARD_PORT0; /* カード挿入ポート番号を設定 */ + func_SDCARD_In(); /* カード挿入コールバック関数呼び出し */ + } + } + } + /* (CTRはポート1のCD端子が未接続(常に挿入状態)なので、ポート1の挿抜チェックは行わない) */ + + /*--- 割り込み要求と割り込みマスクを保存 ---*/ + SD_GetFPGA( SD_INFO1_VALUE, SD_INFO1); + SD_GetFPGA( SD_INFO1_MASK_VALUE, SD_INFO1_MASK); + SD_GetFPGA( SD_INFO2_VALUE, SD_INFO2); + SD_GetFPGA( SD_INFO2_MASK_VALUE, SD_INFO2_MASK); + /*------------------------------------------*/ + + /*--- SD_INFO2のエラーフラグ作成 ---*/ + SD_INFO_ERROR_VALUE = (u16)(SD_INFO2_VALUE & (~SD_INFO2_MASK_VALUE)); + /*--- エラーステータス作成 (RESTIMEOUTとILAエラーのフラグは反映しない) ---*/ + SDCARD_ErrStatus |= SD_INFO_ERROR_VALUE & (~(SD_INFO2_ERR_RESTIMEOUT)) & + (~(SD_INFO2_ERR_ILA)) & SD_INFO2_MASK_ERRSET; + + /*--- RESTIMEOUTとILAエラーはフラグの位置をずらして反映する ---*/ + if( SD_INFO_ERROR_VALUE & SD_INFO2_ERR_ILA) { + SDCARD_ErrStatus |= SDMC_ERR_ILA; /* イリーガルアクセスエラー発生 */ + } + if( SD_INFO_ERROR_VALUE & SD_INFO2_ERR_RESTIMEOUT) { + SDCARD_ErrStatus |= SDMC_ERR_TIMEOUT; /* Response Time out エラー発生 */ + }/*------------------------------------------------------------*/ + + SD_AndFPGA( SD_INFO2,(~(SD_INFO2_ERROR_SET))); /* SD_INFO2のエラーフラグを全て落とす */ + if ( SDCARD_ErrStatus) { /* 何らかのエラーが発生しているか? */ + SD_OrFPGA( SD_INFO2_MASK, SD_INFO2_MASK_ERRSET); /* 全てのエラー割り込みを禁止 */ + } + /*--- SD_INFO2のエラーチェック終了 ---*/ + + + /*--- SD_INFO1の割り込み発生状況フラグ作成 ---*/ + SD_INFO_ERROR_VALUE = (u16)(SD_INFO1_VALUE & (~SD_INFO1_MASK_VALUE)); + + if( SD_INFO_ERROR_VALUE & SD_INFO1_MASK_ALL_END) { /* R/W access all end 割込み発生か? */ + SD_OrFPGA( SD_INFO1_MASK, SD_INFO1_MASK_ALL_END); /* INFO1の access all end 割込み禁止 */ + SDCARD_FPGA_Flag = TRUE; /* R/Wアクセス終了(IP処理完了)フラグセット */ + if( SDCARD_ATC0_Flag) { /* 転送完了処理(SDCARD_ATC0_irq)が完了しているか? */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + SD_TransEndFPGA(); /* 転送終了処理(割り込みマスクを禁止に戻す) */ + if( SDCARD_EndFlag == FALSE) { /* 転送が終了していないか? */ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + if( pSDCARD_info) { /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } /* 転送が終了済みのとき */ + return; + } /* 全ATC完了フラグ OFF の場合 */ + if( SDCARD_ErrStatus != SDMC_NORMAL) { /* エラーが発生している場合 */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + if( SDCARD_EndFlag == FALSE) { /* 転送が終了していないか? */ + SD_TransEndFPGA(); /* カード転送の終了処理 */ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + /* SD_Init(); */ /* SD Cardインターフェース部をリセット&初期設定 */ + if( pSDCARD_info) { /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + } + } /* R/W access all end 割り込み未発生 */ +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_TimerStart + + Description: start timer for measure timeout. + タイムアウト計測を開始する + + Arguments: tim : ms単位のタイムアウト時間 + (50msを超える値の場合は50ms単位になる) + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_TimerStart(u32 tim) +{ +#if (TARGET_OS_CTR == 1) + sta_alm( sdmc_alm_id, tim); + PRINTDEBUG( "Timer Started.\n"); +#else + OSTick tim_tick; + + tim_tick = OS_MilliSecondsToTicks( tim); //us単位からTick単位へ + + OS_CancelAlarm( &sdmc_alm); //アラーム破棄 + OS_SetAlarm( &sdmc_alm, tim_tick, SDCARD_Timer_irq, NULL); //アラームセット +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_TimerStop + + Description: stop timer + タイムアウト計測を停止する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_TimerStop(void) +{ +#if (TARGET_OS_CTR == 1) + stp_alm( sdmc_alm_id); + PRINTDEBUG( "Timer Stopped.\n"); + + //memo:割り込み禁止状態にしてstp_almを呼んでも停止しないので注意 +#else + OS_DisableIrq(); + OS_CancelAlarm( &sdmc_alm); + OS_EnableIrq(); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Timer_irq + + Description: timer interrupt handler. + タイマー割り込みハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Timer_irq(void* arg) +{ +#if (SD_DEBUG_PRINT_ON == 1) + u16 tmp; + + PRINTDEBUG( ">>>Timer intr(Timeout)\n"); + + SDCARD_ErrStatus |= SDMC_ERR_FPGA_TIMEOUT; /* タイムアウトエラービットの設定 */ + + tmp = SD_INFO1; + PRINTDEBUG( "SD_INFO1 : 0x%x\n", tmp); + tmp = SD_INFO1_MASK; + PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", tmp); + tmp = SD_INFO2; + PRINTDEBUG( "SD_INFO2 : 0x%x\n", tmp); + tmp = SD_INFO2_MASK; + PRINTDEBUG( "SD_INFO2_MASK : 0x%x\n", tmp); + tmp = SD_ERR_STS1; + PRINTDEBUG( "SD_ERR_STS1 : 0x%x\n", tmp); +#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + *(vu16*)0x08030200 = 1; +#endif + tmp = SD_ERR_STS2; +#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + *(vu16*)0x08030200 = 0; +#endif + PRINTDEBUG( "SD_ERR_STS2 : 0x%x\n", tmp); + tmp = *(vu16 *)(SD_IF_BASE+0x00); + PRINTDEBUG( "SD_CNT : 0x%x\n", tmp); + tmp = SD_SECCNT; + PRINTDEBUG( "SD_SECCNT : 0x%x\n", tmp); +#endif + + + if(SDCARD_EndFlag == FALSE){ /* 転送処理完了フラグの確認(クリア?)*/ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグをセット */ + /* SD_TransEndFPGA(); */ /* カード転送の終了処理 */ + /* SD_StopTransmission(); */ /* カード転送終了設定 */ + /* SD_Init(); */ /* SD Cardインターフェース部をリセット&初期設定 */ + if(pSDCARD_info){ /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus;/* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + + /**/ + PRINTDEBUG( "--Wup sdTsk(Time)--\n"); +#if (TARGET_OS_CTR == 1) + iwup_tsk( sdmc_tsk_id); + PRINTDEBUG( "id : 0x%x\n", sdmc_tsk_id); +#else + sdmc_wakeup_count++; + PRINTDEBUG( "wakeup\n"); + OS_WakeupThreadDirect( &sdmc_tsk); +#endif +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcSendSCR + + Description: get SCR register. + SCRを取得する(DATライン経由で8バイト送られてくる)。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcSendSCR(void) +{ + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + + SD_EnableClock(); /* SD-CLK Enable */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 8; /* SCR レジスタ 転送サイズ 8bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 8byte 設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + if(SD_AppCommand()){ /* RCA設定後 CMD55発行処理が正常終了しない? */ + SD_DisableClock(); /* SD-CLK Disable */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; /* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = SD_SCR; /* データ格納バッファのアドレスを設定 */ + + /* 転送前の準備処理 */ + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if SCR_ON + thread_flag = TRUE; + SD_SendSCR(); /* SCRの取得コマンド発行 */ + PRINTDEBUG( "==Slp Tsk==\n"); +#if (TARGET_OS_CTR == 1) + //can_wup( 0); + slp_tsk(); +#else + /*--------------------*/ +// OS_TPrintf( "sleep %d\n", __LINE__); +// OS_SleepThread( NULL); + /*--------------------*/ +#endif + PRINTDEBUG( "waked\n"); + thread_flag = FALSE; + + while(!SDCARD_EndFlag){ /* カードアクセス終了待ち */ + PRINTDEBUG( "k\n"); + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + } + + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータスの取得コマンド発行処理 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理 */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ +#endif + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを戻す(default:512bytes)*/ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + + SD_DisableClock(); /* SD-CLK Disable */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcErrProcess + + Description: when error is occured, get Card Status to check and stop the + transfer. + エラー発生時の処理。カードステータスを取得し、データ転送中で + あればストップさせる。 + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcErrProcess(void) +{ + u16 usRSP0; + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_ERRPROC_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + + SD_SendStatus(); /* CMD13 addressed card sends its status register 発行、レスポンス待ち */ + + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + SD_GetFPGA( usRSP0, SD_RSP0); + usRSP0 = (u16)(( usRSP0 & RSP_R1_CURRENT_STATE) >> 1); /* カレントステートを取り出す */ + if((usRSP0 == CURRENT_STATE_DATA) || (usRSP0 == CURRENT_STATE_RCV)){ /* SDCARD Status が data rcv の時 */ + SD_Command(SD_CMD_CMD | STOP_TRANSMISSION); /* CMD12(StopTransmission)発行処理 */ + } + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcGetCardSize + + Description: get card size (number of sectors). + カードのセクタ数を取得する + + Arguments: None + + Returns: number of sectors in the SD card which inserted. + *---------------------------------------------------------------------------*/ +u32 sdmcGetCardSize(void) +{ + /* カード全セクタ数 (SDCARD_Layer_Init関数内で算出される) */ + return ulSDCARD_Size; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_SD_Status + + Description: get SD Status. + SDステータスを取得する(DATライン経由で64バイト送られてくる)。 + カードステータスではないことを留意。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 SDCARD_SD_Status(void) +{ + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + u32 ulSaveRestSectorCount; /* 残りセクタサイズ保存用 */ + + SD_EnableClock(); /* SD-CLK Enable */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 64; /* SD_STATUS 転送サイズ 64bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 64byte 設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + if(SD_AppCommand()){ /* RCA設定後 CMD55発行処理 が正常終了しない?*/ + SD_DisableClock(); /* SD-CLK Disable */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSaveRestSectorCount = ulSDCARD_RestSectorCount; /* 残りセクタサイズを保存(TODO:いらない?) */ + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; /* 残りセクタサイズ、セクタカウントを1に設定 */ + pSDCARD_BufferAddr = SD_SDSTATUS; /* データ格納バッファのアドレスを設定 */ + + /* 転送前の準備処理 */ + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + thread_flag = TRUE; + SD_SDStatus(); /* ACMD13 SD_STATUSの取得コマンド発行処理 */ + PRINTDEBUG( "==Slp Tsk==\n"); +#if (TARGET_OS_CTR == 1) + //can_wup( 0); + slp_tsk(); +#else + /*--------------------*/ +// OS_TPrintf( "sleep %d\n", __LINE__); +// OS_SleepThread( NULL); + /*--------------------*/ +#endif + PRINTDEBUG( "waked\n"); + thread_flag = FALSE; + + while(!SDCARD_EndFlag){ /* カードアクセス終了待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + } + + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスが何らかのエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータス取得コマンド発行、レスポンス(R1)待ち */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理 */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを戻す(default:512bytes)*/ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + ulSDCARD_RestSectorCount = ulSaveRestSectorCount; /* 保存していた残りセクタサイズを戻す(TODO:いらない?)*/ + + SD_DisableClock(); /* SD-CLK Disable */ + + return SDCARD_ErrStatus; +} + +/*******************************************************************************/ +int MMCP_SetBusWidth( BOOL b4bit) +{ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ +// u16 TestData; + u16 Resid; + + SD_EnableClock(); /* SD-CLK Enable */ + +#if 0 + TestData = 0x5A;//0xA5; + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 4; /* 転送サイズ 1バイト */ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 1byte 設定 */ +#endif + /*コマンド6発行*/ + MMCP_WriteBusWidth( b4bit); + SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */ + +#if 0 + /**/ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; + pSDCARD_BufferAddr = &TestData; /* データ格納バッファのアドレスを設定 */ + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + /* IPのSD_SECCNTレジスタ有効化、転送セクタ数設定(自動CMD12発行のため) */ +// SD_EnableSeccnt( ulSDCARD_RestSectorCount); + + /*バステスト*/ + MMCP_BusTest( FALSE); + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + + /**/ + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1;/* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = &Resid; /* データ格納バッファのアドレスを設定 */ + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + /**/ + MMCP_BusTest( TRUE); + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + if( SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + /*バステスト合格ならバス幅を4bitに拡張*/ +// if( TestData == (~(Resid))) { + if( Resid == 0xA5) { + SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */ + }else{ + SD_OrFPGA(SD_OPTION,(SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(1bit幅) */ + } + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを設定(デフォルト 512bytesに戻す)*/ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ +#endif + return( 0); +} +/*******************************************************************************/ + + +/*---------------------------------------------------------------------------* + Name: i_sdmcCheckWP + + Description: check the write protect bit in the SD_INFO1 register. + SD_INFO1レジスタのライトプロテクトビットを調べる + (0:ライトプロテクトされている、1:ライトプロテクトされていない)。 + CTRではポート1は常に1。 + + Arguments: None + + Returns: number of sectors in the SD card which inserted. + *---------------------------------------------------------------------------*/ +static u16 i_sdmcCheckWP(void) +{ + if (SD_port_number == SDCARD_PORT0) /* ポート0のとき */ + { + if(!(SD_CheckFPGAReg(SD_INFO1,SD_INFO1_WRITEPROTECT))) { //WPフラグが立っていないか? + SDCARD_ErrStatus |= SDMC_ERR_WP; //エラーフラグのWPエラービットを立てる + }else{ //WPフラグが立っていたとき + SDCARD_ErrStatus &= ~SDMC_ERR_WP; //エラーフラグのWPエラービットを落とす + } + return SDCARD_ErrStatus; + } + else if (SD_port_number == SDCARD_PORT1) /* ポート1のとき */ + { /*TWLのポート1はライトプロテクトビットが常に0(プロテクト状態)なので反転して評価*/ + if((SD_CheckFPGAReg(EXT_WP,EXT_WP_PORT1))) { //WPフラグが立っていないか? + SDCARD_ErrStatus |= SDMC_ERR_WP; //エラーフラグのWPエラービットを立てる + }else{ //WPフラグが立っていたとき + SDCARD_ErrStatus &= ~SDMC_ERR_WP; //エラーフラグのWPエラービットを落とす + } + return SDCARD_ErrStatus; + } + return SDMC_ERR_END; //ここには来ない +} + +/*---------------------------------------------------------------------------* + Name: sdmcWriteFifo + + Description: write to card. + ラッパーのFIFOを使用してカードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcWriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 recv_dat; +#else + OSMessage recv_dat; +#endif + SDMC_ERR_CODE api_result; + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_WRITE_WITH_FIFO; + +#if (TARGET_OS_CTR == 1) + snd_dtq( sdmc_dtq_id, (VP_INT)&SdMsg); + + /* 返り値待ち */ + rcv_dtq( sdmc_result_dtq_id, (VP_INT*)&recv_dat); + + api_result = (SDMC_ERR_CODE)recv_dat; +#else + recv_dat = (OSMessage)&SdMsg; + OS_SendMessage( &sdmc_dtq, recv_dat, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ + OS_ReceiveMessage( &sdmc_result_dtq, &recv_dat, OS_MESSAGE_BLOCK); + api_result = (SDMC_ERR_CODE)recv_dat; +#endif + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_WriteFifo + + Description: write to card. + ラッパーのFIFOを使用してカードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_WriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDMC_ERR_CODE result; + + /* FIFO割り込み禁止 */ + *(SDIF_CNT) = (*(SDIF_CNT) & (~(SDIF_CNT_FFIE | SDIF_CNT_FEIE))); + *(SDIF_FDS) = (u16)SDCARD_SectorSize; /* FIFOのデータサイズ */ + *(SDIF_FSC) = bufsize; + *(SDIF_CNT) |= SDIF_CNT_USEFIFO; /* FIFO使用フラグON */ + CC_EXT_MODE = CC_EXT_MODE_DMA; /* DMAモードON */ + + result = SDCARDi_Write( buf, bufsize, offset, func, info); + + /* FIFO無効に */ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* FIFO使用フラグOFF */ + CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */ + + return result; +} + +/*---------------------------------------------------------------------------* + Name: sdmcWrite + + Description: write to card. + カードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcWrite(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; +#if (TARGET_OS_CTR == 1) + u32 recv_dat; +#else + OSMessage recv_dat; +#endif + SDMC_ERR_CODE api_result; + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_WRITE; + +#if (TARGET_OS_CTR == 1) + snd_dtq( sdmc_dtq_id, (VP_INT)&SdMsg); + + /* 返り値待ち */ + rcv_dtq( sdmc_result_dtq_id, (VP_INT*)&recv_dat); + + api_result = (SDMC_ERR_CODE)recv_dat; +#else + recv_dat = (OSMessage)&SdMsg; + OS_SendMessage( &sdmc_dtq, recv_dat, OS_MESSAGE_BLOCK); + + /* 返り値待ち */ + OS_ReceiveMessage( &sdmc_result_dtq, &recv_dat, OS_MESSAGE_BLOCK); + api_result = (SDMC_ERR_CODE)recv_dat; +#endif + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_Write + + Description: write to card. + カードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_Write(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + s16 nRetryCount; + u32 ulResid; + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + + if( func != NULL){ /* コールバック関数のNullチェック */ + return SDMC_ERR_PARAM; /* コマンドパラメータエラー */ + } + +#if WP_ena + if( i_sdmcCheckWP()) { + return SDMC_ERR_WP; /*** ライトプロテクトのチェック ***/ + } +#endif + for(nRetryCount = 0;nRetryCount < SDCARD_RETRY_COUNT;nRetryCount++){ + + SD_EnableClock(); /* SD-CLK Enable */ + +/* func_SDCARD_CallBack = func; */ + pSDCARD_info = info; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = bufsize; + pSDCARD_BufferAddr = buf; /* データ格納バッファのアドレスを設定 */ + + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + /* IPのSD_SECCNTレジスタ有効化、転送セクタ数設定(自動CMD12発行のため) */ + SD_EnableSeccnt( ulSDCARD_RestSectorCount); + + /*--- ライトコマンド発行 ---*/ + if( SDCARD_SDHCFlag) { + SD_MultiWriteBlock( offset); /* ライトコマンド発行(引数:オフセット) */ + }else{ + SD_MultiWriteBlock( offset * SDCARD_SectorSize); /* ライトコマンド発行(引数:オフセット*セクタサイズ) */ + } + /*--------------------------*/ + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + /* エラーが発生していないか、タイムアウト以外のエラーの場合 */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータスの取得コマンド発行処理 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if( SDCARD_ErrStatus) { /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理(status取得、強制停止) */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; /* エラー終了 */ + } +#if RESID + if( SDCARD_SDFlag) { /* SDカード(MMCでない)の場合 */ + if( SDCARD_UseFifoFlag) { /*--- FIFOを使用しているときは ---*/ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* 一時的にFIFO未使用モードにする */ + CC_EXT_MODE = CC_EXT_MODE_PIO; + i_sdmcGetResid(&ulResid); /* 書き込み完了セクタ数の取得 */ + *(SDIF_CNT) |= SDIF_CNT_USEFIFO; /* FIFO使用モードに戻す */ + CC_EXT_MODE = CC_EXT_MODE_DMA; + }else{ /*--- FIFOを使用していないとき ---*/ + i_sdmcGetResid(&ulResid); /* 書き込み完了セクタ数の取得 */ + } + if(info){ + info->resid = ulResid * SDCARD_SectorSize;/*** pSDCARD_info->resid をinfo->resid に修正 柏 2000.08.31. ***/ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + } +#endif + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ +#if RESID + if( SDCARD_SDFlag) { /* SDカード(MMCでない)の場合 */ + if( bufsize != ulResid){ /* ライト済みセクタ数が正しくないか? */ + SD_SetErr( SDMC_ERR_NUM_WR_SECTORS); /* エラーフラグセット */ + } + } +#endif + if( SDCARD_ErrStatus == SDMC_NORMAL) { /* エラーステータスの確認(エラー無し?)*/ + break; + } + } + + SD_DisableClock(); /* クロック供給停止 */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcGetResid + + Description: get the numbers of the well written(without errors) blocks. + 書き込みが完了したセクタの数を取得する。 + + + Arguments: pResid : 書き込み完了セクタ数を返す変数へのポインタ + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcGetResid(u32 *pResid) +{ + u16 Resid[2]; + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 4; /* 転送サイズ 4バイト */ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 4byte 設定 */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(4000msec) */ +#endif + + if( SD_AppCommand()) { /* RCA設定後 CMD55発行処理 */ + return SDCARD_ErrStatus; /* エラー発生(CMD55が正常終了しない)なら戻る */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1;/* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = Resid; /* データ格納バッファのアドレスを設定 */ + + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + thread_flag = TRUE; + /*--- ACMD22 ライト済みセクタ数取得コマンド発行 ---*/ + SD_SendNumWRSectors(); + /*-------------------------------------------------*/ + PRINTDEBUG( "==Slp Tsk==\n"); +#if (TARGET_OS_CTR == 1) +// can_wup( 0); + slp_tsk(); +#else + /*--------------------*/ +// OS_TPrintf( "sleep %d\n", __LINE__); +// OS_SleepThread( NULL); + /*--------------------*/ +#endif + PRINTDEBUG( "waked\n"); + thread_flag = FALSE; + + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + if( SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + /* エラーが発生していないか、タイムアウト以外のエラーの場合 */ + if( SDCARD_ErrStatus) { /* (タイムアウト以外に)エラー発生か? */ + i_sdmcErrProcess(); /* エラー時の処理 */ + *pResid = 0L; /* ライト済みセクタ数に 0 を設定 */ + }else{ /* エラーが発生していない場合 */ + /* SDカードのレジスタはMSBから送られてくるため並べ替えを行う */ + Resid[1] = SD_SwapByte(&Resid[1]); /* 上位 1byte と下位 1byte を入れ替える */ + (((LELONG *)pResid)->dt2word.low) = Resid[1]; /* Resid[1]の設定 */ + Resid[0] = SD_SwapByte(&Resid[0]); /* 上位 1byte と下位 1byte を入れ替える */ + (((LELONG *)pResid)->dt2word.high) = Resid[0]; /* Resid[0]の設定 */ + } + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを設定(デフォルト 512bytesに戻す)*/ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + /* SetBlockLengthでエラーが出たらどうする? */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Restore_port0 + + Description: restore registers and variables of port0. + ポート0のレジスタや変数を復帰する。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Restore_port0(void) +{ + /* registers */ + SD_SetFPGA( SD_CLK_CTRL, SDPort0Context.SD_CLK_CTRL_VALUE); + SD_SetFPGA( SD_OPTION, SDPort0Context.SD_OPTION_VALUE); + + /* variables */ + SD_RCA = SDPort0Context.SD_RCA; + SDCARD_ErrStatus = SDPort0Context.ErrStatus; + SDCARD_Status = SDPort0Context.Status; + SDCARD_MMCFlag = SDPort0Context.MMCFlag; + SDCARD_SDHCFlag = SDPort0Context.SDHCFlag; + SDCARD_SDFlag = SDPort0Context.SDFlag; + + SDCARD_OutFlag = SDPort0Context.OutFlag; + pSDCARD_info = NULL; + + /*media registers*/ + MI_CpuCopy8( SDPort0Context.SD_CID, SD_CID, 16); + MI_CpuCopy8( SDPort0Context.SD_CSD, SD_CSD, 16); + MI_CpuCopy8( SDPort0Context.SD_OCR, SD_OCR, 4); + MI_CpuCopy8( SDPort0Context.SD_SCR, SD_SCR, 8); + + /*recalc*/ + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Restore_port1 + + Description: restore registers and variables of port0. + ポート1のレジスタや変数を復帰する。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_Restore_port1(void) +{ + /* registers */ + SD_SetFPGA( SD_CLK_CTRL, SDPort1Context.SD_CLK_CTRL_VALUE); + SD_SetFPGA( SD_OPTION, SDPort1Context.SD_OPTION_VALUE); + + /* variables */ + SD_RCA = SDPort1Context.SD_RCA; + SDCARD_ErrStatus = SDPort1Context.ErrStatus; + SDCARD_Status = SDPort1Context.Status; + SDCARD_MMCFlag = SDPort1Context.MMCFlag; + SDCARD_SDHCFlag = SDPort1Context.SDHCFlag; + SDCARD_SDFlag = SDPort1Context.SDFlag; + + SDCARD_OutFlag = SDPort1Context.OutFlag; + pSDCARD_info = NULL; + + /*media registers*/ + MI_CpuCopy8( SDPort1Context.SD_CID, SD_CID, 16); + MI_CpuCopy8( SDPort1Context.SD_CSD, SD_CSD, 16); + MI_CpuCopy8( SDPort1Context.SD_OCR, SD_OCR, 4); + MI_CpuCopy8( SDPort1Context.SD_SCR, SD_SCR, 8); + + /*recalc*/ + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); +} + + +/*---------------------------------------------------------------------------* + Name: sdmcSelectedNo + + Description: get selected port number. + 選択されているポート番号を取得する + + Arguments: None + + Returns: [15:8]port numbers which supported(サポートされているポート数) + [7:0]port number which selected now(選択されているポート番号) + *---------------------------------------------------------------------------*/ +u16 sdmcSelectedNo(void) +{ + u16 i_sdmcSelect_Value; + + SD_GetFPGA(i_sdmcSelect_Value,SD_PORTSEL); /* SD_PORTSELレジスタ値を取得 */ + + return i_sdmcSelect_Value; +} + +/*---------------------------------------------------------------------------* + Name: sdmcSelect + + Description: select port. + ポートを選択する + + Arguments: select : [15:8]port numbers which supported(サポートされているポート数) + [7:0]port number which selected now(選択するポート番号) + Returns: 0 : success + >0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcSelect(u16 select) +{ + union + { + u16 Val; + struct + { + u8 L; /* 指定したいポート */ + u8 H; /* サポートされているポート */ + } PSel; + } SDCARD_PSel; + + //TODO : transferモードからstand-byモードにする? +/* if( !SDCARD_EndFlag) { // 転送が残っている場合はエラー + return SDMC_ERR_END; + } +*/ + SDCARD_PSel.Val = select; + if ((SDCARD_PSel.PSel.H > SDCARD_PORT_NO_MAX) + | (SDCARD_PSel.PSel.H < SDCARD_PORT_NO_MIN) + | (SDCARD_PSel.PSel.L > SDCARD_PORT_SELECT_NO)) + { + return SDMC_ERR_PARAM; /* コマンドパラメータエラー */ + }else{ + SD_port_en_numbers = SDCARD_PSel.PSel.H; /* 新しくサポートするポート数を保存 */ + SD_port_number = SDCARD_PSel.PSel.L; /* 新しく選択するポート番号を保存 */ + + SD_GetFPGA(SDCARD_PSel.Val,SD_PORTSEL); /* 現在のレジスタを取得 */ + + if (SDCARD_PSel.PSel.L == 0) /* 現在選択されているポートが 0 ? */ + { + SDCARD_Backup_port0(); + }else{ + SDCARD_Backup_port1(); + } + + SDCARD_PSel.Val= select; + + if (SDCARD_PSel.PSel.L == 0) /* 新しく選択されたポートが 0 ? */ + { + SDCARD_Restore_port0(); + }else{ + SDCARD_Restore_port1(); + } + + SD_SetFPGA(SD_PORTSEL,select); /* レジスタへセット */ + return SDMC_NORMAL; /* 0 リターン */ + } +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_Thread + + Description: SDメモリカードメインタスク + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Thread( void* arg) +{ + SDCARDMsg* SdMsg; +#if (TARGET_OS_CTR == 1) + u32 current_dat; +#else + OSMessage current_dat; +#endif + SDMC_ERR_CODE api_result; + + while( TRUE) { + /* メッセージ待ち */ + PRINTDEBUG( "rcv mes sdThread\n"); +#if (TARGET_OS_CTR == 1) + rcv_dtq( sdmc_dtq_id, (VP_INT*)¤t_dat); +#else + OS_ReceiveMessage( &sdmc_dtq, ¤t_dat, OS_MESSAGE_BLOCK); +#endif + SdMsg = (SDCARDMsg*)current_dat; + PRINTDEBUG( "sd task : receive command : %d\n", SdMsg->operation); + + switch( SdMsg->operation) { + case SD_OPERATION_INIT: + api_result = i_sdmcInit(); + break; + case SD_OPERATION_READ: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_Read( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + case SD_OPERATION_READ_WITH_FIFO: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_ReadFifo( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + case SD_OPERATION_WRITE: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_Write( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + case SD_OPERATION_WRITE_WITH_FIFO: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_WriteFifo( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + default: + PRINTDEBUG( "sdmc-thread error : undefined command.\n"); + api_result = SDMC_ERR_COMMAND; + break; + } + + PRINTDEBUG( "sd task : operation ends(result : 0x%x), send message begin\n", api_result); + + /*メッセージ返送*/ + current_dat = (OSMessage)api_result; +#if (TARGET_OS_CTR == 1) + snd_dtq( sdmc_result_dtq_id, (VP_INT)api_result); +#else + OS_SendMessage( &sdmc_result_dtq, current_dat, OS_MESSAGE_BLOCK); +#endif + } +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Intr_Thread + + Description: SDメモリカード割り込み処理タスク + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Intr_Thread( void* arg) +{ + u16 sd_info1;//, sd_info2; + OSIntrMode enabled; + + while( 1) { + PRINTDEBUG( "next_tsk:0x%x\n", OS_SelectThread()); + PRINTDEBUG( "Slp sdIntr\n"); + + OS_WaitIrq( FALSE, OS_IE_SD1); +// OS_DisableIrqMask( OS_IE_SD1); +// if( sdmc_intr_wakeup_count == 0) { +// OS_SleepThread( NULL); +// } +// sdmc_intr_wakeup_count--; +// OS_EnableIrqMask( OS_IE_SD1); +// enabled = OS_DisableInterrupts(); + (void)OS_ClearIrqCheckFlag( OS_IE_SD1); + /*SD割り込みのIF解除*/ + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; +// (void)OS_RestoreInterrupts( enabled); + PRINTDEBUG( "sdIntr waked\n"); + + /*--- FIFOを使うとき ---*/ + if( SDCARD_UseFifoFlag) { + sd_info1 = SD_INFO1; + if( ((*SDIF_CNT & SDIF_CNT_FULL)&&(*SDIF_CNT & SDIF_CNT_FFIE)) || + ((!(*SDIF_CNT & SDIF_CNT_NEMP))&&(*SDIF_CNT & SDIF_CNT_FEIE))) { + + PRINTDEBUG( ">>>SD Intr(FIFO)\n");// Full or Empty)\n"); + OS_DisableIrqMask( OS_IE_SD1); + SDCARD_FPGA_irq(); /*カードからのリードライト要求割り込み*/ + OS_EnableIrqMask( OS_IE_SD1); + /* FIFO割り込みとALLEND割り込みがほぼ同時の場合に対応 */ + if( SD_CheckFPGAReg( sd_info1, SD_INFO1_ALL_END)) { + (void)OS_ClearIrqCheckFlag( OS_IE_SD1); + /*SD割り込みのIF解除*/ + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; + OS_DisableIrqMask( OS_IE_SD1); + SYSFPGA_irq(); + OS_EnableIrqMask( OS_IE_SD1); + if( thread_flag) { + PRINTDEBUG( "--Wup sdThread!--\n"); + sdmc_wakeup_count++; + PRINTDEBUG( "wakeup\n"); + OS_WakeupThreadDirect( &sdmc_tsk); + } + } + }else{ + if( SD_CheckFPGAReg( SD_INFO2, (SD_INFO2_MASK_BRE | SD_INFO2_MASK_BWE))) { + PRINTDEBUG ( ">>>SD Intr(R/W Req)\n"); + //ここで自動的にラッパーのFIFO<->SD_BUF0間で通信が行われる + // if((!(*SDIF_CNT & SDIF_CNT_NEMP))&&(*SDIF_CNT & SDIF_CNT_FEIE)) { + OS_DisableIrqMask( OS_IE_SD1); + SDCARD_FPGA_irq(); + OS_EnableIrqMask( OS_IE_SD1); + }else{ + PRINTDEBUG( ">>>SD Intr(End or Err)\n"); + OS_DisableIrqMask( OS_IE_SD1); + SYSFPGA_irq(); /*完了またはエラー割り込み*/ + OS_EnableIrqMask( OS_IE_SD1); + /**/ + if( thread_flag) { + PRINTDEBUG( "--Wup sdThread!--\n"); + sdmc_wakeup_count++; + OS_WakeupThreadDirect( &sdmc_tsk); + } + } + } + /*--- FIFOを使わないとき ---*/ + }else{ + if( SD_CheckFPGAReg( SD_INFO2, (SD_INFO2_MASK_BRE | SD_INFO2_MASK_BWE))) { + PRINTDEBUG( ">>>SD Intr(R/W Req)\n"); + OS_DisableIrqMask( OS_IE_SD1); + SDCARD_FPGA_irq(); /*カードからのリードライト要求割り込み*/ + OS_EnableIrqMask( OS_IE_SD1); + }else{ + PRINTDEBUG( ">>SD Intr(End or Err)\n"); + OS_DisableIrqMask( OS_IE_SD1); + SYSFPGA_irq(); /*完了またはエラー割り込み*/ + OS_EnableIrqMask( OS_IE_SD1); + /**/ + if( thread_flag) { + PRINTDEBUG( "--Wup sdThread!--\n"); + sdmc_wakeup_count++; + OS_WakeupThreadDirect( &sdmc_tsk); + } + } + } + } +} diff --git a/build/libraries/fatfs/ARM7/firm_sdmc/sdmc_port.c b/build/libraries/fatfs/ARM7/firm_sdmc/sdmc_port.c new file mode 100644 index 00000000..c7f8da48 --- /dev/null +++ b/build/libraries/fatfs/ARM7/firm_sdmc/sdmc_port.c @@ -0,0 +1,246 @@ +/*---------------------------------------------------------------------------* + Project: + File: sdmc_port.c + + Copyright 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. + + $Log: sdmc_port.c,v $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#include +#include "sdmc_config.h" +#include "sdif_reg.h" +#include +#include "sdif_ip.h" + + +// #define PRINTDEBUG OS_TPrintf + #define PRINTDEBUG( ...) ((void)0) + + + +/*extern変数(sdmc.c)*/ +extern u32 SDCARD_SectorSize; /* セクタサイズ デフォルト 512bytes */ +extern SDMC_ERR_CODE SDCARD_ErrStatus; /* エラーステータス */ +extern volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ + + +extern SDPortContext SDPort0Context; +extern SDPortContext SDPort1Context; + + +/*extern関数(sdmc.c)*/ +extern void i_sdmcCalcSize( void); +extern void SDCARD_Backup_port1(void); +extern void SDCARD_Restore_port1(void); +extern SDMC_ERR_CODE SDCARD_Layer_Init(void); +extern void SDCARD_TimerStop(void); /* タイムアウト計測停止 */ + +static SDMC_ERR_CODE i_sdmcSavePortContext( SDPortContext* buf_adr, u16 port_no); +static SDMC_ERR_CODE i_sdmcLoadPortContext( SDPortContext* buf_adr, u16* port_no); + +static void sdmcPrintContext( SDPortContext* targ); + + +/*---------------------------------------------------------------------------* + Name: sdmcClearPortContext + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void sdmcClearPortContext( SDPortContext* buf_adr) +{ + MI_CpuFill8( buf_adr, 0x00, sizeof(SDPortContext)); +} + +/*---------------------------------------------------------------------------* + Name: sdmcCheckPortContext + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcCheckPortContext( SDPortContext* buf_adr) +{ + if( (buf_adr->SD_CID[0] != 0)&&(buf_adr->port_no < 2)) { + return( SDMC_NORMAL); + }else{ + return( SDMC_ERR_PARAM); + } +} + +/*---------------------------------------------------------------------------* + Name: sdmcSavePortContext + + Description: ポート0のレジスタや変数をユーザバッファに退避する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcSavePortContext( SDPortContext* buf_adr, u16 port_no) +{ + if( buf_adr == NULL) { + return( SDMC_ERR_PARAM); + } + switch( port_no) { + case 0: + MI_CpuCopy8( &SDPort0Context, buf_adr, sizeof(SDPortContext)); + buf_adr->port_no = 0; + break; + case 1: + MI_CpuCopy8( &SDPort1Context, buf_adr, sizeof(SDPortContext)); + buf_adr->port_no = 1; + break; + default: return( SDMC_ERR_PARAM); + } + return( SDMC_NORMAL); +} + +/*---------------------------------------------------------------------------* + Name: sdmcLoadPortContext + + Description: ポート0のレジスタや変数をユーザバッファから復帰する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcLoadPortContext( SDPortContext* buf_adr, u16* port_no) +{ + if( buf_adr == NULL) { + return( SDMC_ERR_PARAM); + } + switch( buf_adr->port_no) { + case 0: + MI_CpuCopy8( buf_adr, &SDPort0Context, sizeof(SDPortContext)); + *port_no = 0; + break; + case 1: + MI_CpuCopy8( buf_adr, &SDPort1Context, sizeof(SDPortContext)); + *port_no = 1; + break; + default: return( SDMC_ERR_PARAM); + } + return( SDMC_NORMAL); +} + + + +/*---------------------------------------------------------------------------* + Name: i_sdmcMPInitFirm + + Description: initialize SD card in multi ports. + マルチポートのSDカード初期化 + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE i_sdmcMPInitFirm( void) +{ + u16 load_port_no; + SDPortContext* SDNandContext; + + //予約領域のポートコンテキスト参照 + SDNandContext = (SDPortContext*)&(((OSFromBromBuf*)OSi_GetFromBromAddr())->SDNandContext); + +#if 0 + sdmcPrintContext( SDNandContext); +#endif + + //NANDスロットの初期化 + SD_SetFPGA( SD_PORTSEL, SDMC_PORT_NAND); /* NANDポート選択 */ + + PRINTDEBUG( "SDNandContext : 0x%x\n", SDNandContext); + //初期化済みでないときだけ初期化 + if( sdmcCheckPortContext( SDNandContext) != SDMC_NORMAL) { + PRINTDEBUG( "sdmcCheckPortContext : ERR!\n"); + SDCARD_ErrStatus = SDCARD_Layer_Init(); + + SDCARD_Backup_port1(); //TODO:ポート番号 + //ポートコンテキストの保存 + if( i_sdmcSavePortContext( SDNandContext, 1) != SDMC_NORMAL) { + PRINTDEBUG( "i_sdmcSavePortContext failed\n"); + return( SDMC_ERR_PARAM); + } + }else{ //ポートコンテキストの復帰 + PRINTDEBUG( "sdmcCheckPortContext : NORMAL\n"); + + /*SDCARD_Layer_Init()の代わり*/ + SDCARD_SectorSize = SECTOR_SIZE; /* セクタサイズ デフォルト 512bytes */ +// SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_128)); /* SDクロックの周波数 261KHz(初期化時は100〜400khz) */ + + if( i_sdmcLoadPortContext( SDNandContext, &load_port_no) != SDMC_NORMAL) { + PRINTDEBUG( "i_sdmcLoadPortContext failed\n"); + return( SDMC_ERR_PARAM); + } + SDCARD_Restore_port1(); //TODO:load_port_no値判定 + } + + SDCARD_OutFlag = FALSE; /* 排出フラグをリセット */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + SD_DisableClock(); /* SD-CLK Disable */ + SD_EnableInfo(); /* SD Card 挿抜 割り込み許可 */ + + return SDCARD_ErrStatus; +} + + +/*デバッグ用*/ +static void sdmcPrintContext( SDPortContext* targ) +{ + OS_TPrintf( "CID[0]:0x%x\n", targ->SD_CID[0]); + OS_TPrintf( "CID[1]:0x%x\n", targ->SD_CID[1]); + OS_TPrintf( "CID[2]:0x%x\n", targ->SD_CID[2]); + OS_TPrintf( "CID[3]:0x%x\n", targ->SD_CID[3]); + OS_TPrintf( "CID[4]:0x%x\n", targ->SD_CID[4]); + OS_TPrintf( "CID[5]:0x%x\n", targ->SD_CID[5]); + OS_TPrintf( "CID[6]:0x%x\n", targ->SD_CID[6]); + OS_TPrintf( "CID[7]:0x%x\n\n", targ->SD_CID[7]); + + OS_TPrintf( "CSD[0]:0x%x\n", targ->SD_CSD[0]); + OS_TPrintf( "CSD[1]:0x%x\n", targ->SD_CSD[1]); + OS_TPrintf( "CSD[2]:0x%x\n", targ->SD_CSD[2]); + OS_TPrintf( "CSD[3]:0x%x\n", targ->SD_CSD[3]); + OS_TPrintf( "CSD[4]:0x%x\n", targ->SD_CSD[4]); + OS_TPrintf( "CSD[5]:0x%x\n", targ->SD_CSD[5]); + OS_TPrintf( "CSD[6]:0x%x\n", targ->SD_CSD[6]); + OS_TPrintf( "CSD[7]:0x%x\n\n", targ->SD_CSD[7]); + + OS_TPrintf( "OCR[0]:0x%x\n", targ->SD_OCR[0]); + OS_TPrintf( "OCR[1]:0x%x\n\n", targ->SD_OCR[1]); + + OS_TPrintf( "SCR[0]:0x%x\n", targ->SD_SCR[0]); + OS_TPrintf( "SCR[1]:0x%x\n\n", targ->SD_SCR[1]); + + OS_TPrintf( "RCA:0x%x\n\n", targ->SD_RCA); + + OS_TPrintf( "MMCFlag :0x%x\n", targ->MMCFlag); + OS_TPrintf( "SDHCFlag:0x%x\n", targ->SDHCFlag); + OS_TPrintf( "SDFlag :0x%x\n\n", targ->SDFlag); + + OS_TPrintf( "ErrStatus:0x%x\n", targ->ErrStatus); + OS_TPrintf( "Status:0x%x\n\n", targ->Status); + + OS_TPrintf( "SD_CLK_CTRL_VALUE:0x%x\n", targ->SD_CLK_CTRL_VALUE); + OS_TPrintf( "SD_OPTION_VALUE :0x%x\n\n", targ->SD_OPTION_VALUE); + + OS_TPrintf( "OutFlag:0x%x\n\n", targ->OutFlag); + + OS_TPrintf( "port_no:0x%x\n", targ->port_no); +} diff --git a/build/libraries/fatfs/ARM7/rom_sdmc/drsdmc.c b/build/libraries/fatfs/ARM7/rom_sdmc/drsdmc.c new file mode 100644 index 00000000..d1c9035f --- /dev/null +++ b/build/libraries/fatfs/ARM7/rom_sdmc/drsdmc.c @@ -0,0 +1,686 @@ +/*---------------------------------------------------------------------------* + Project: TwlBrom - rtfs interface for SD Memory Card + File: drsdmc.h + + Copyright 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 +#include +//#if (INCLUDE_SD) + +#include "sdmc_config.h" +//#include "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 + #define PRINTDEBUG vlink_dos_printf + #endif +#else + #define PRINTDEBUG( ...) ((void)0) +#endif + + +#define NUM_SD_PAGES +#define SD_PAGE_SIZE + + +/*---------------------------------------------------------------------------* + extern変数 + *---------------------------------------------------------------------------*/ +//extern ER_ID sdmc_dtq_id; +//extern ER_ID sdmc_result_dtq_id; +extern void (*func_SDCARD_In)(void); /* カード挿入イベント用コールバック保存用 */ +extern void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */ +extern volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ + +extern int rtfs_first_stat_flag[26]; + +/*SDメモリカードのスペック構造体*/ +extern SdmcSpec sdmc_current_spec; + + +/*---------------------------------------------------------------------------* + extern関数 + *---------------------------------------------------------------------------*/ +extern SDMC_ERR_CODE sdmcGoIdle(void (*func1)(),void (*func2)()); + + +/*---------------------------------------------------------------------------* + static変数 + *---------------------------------------------------------------------------*/ +static int sdmc_drive_no; +void (*func_usr_sdmc_out)(void) = NULL; /* カード排出イベントのユーザコールバック */ + + +/*---------------------------------------------------------------------------* + static関数 + *---------------------------------------------------------------------------*/ +void i_sdmcRemovedIntr( void); +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: sdmcCheckMedia + + Description: MBRのシグネチャおよび + パーティションのフォーマット種別をチェックする + + Arguments: + + Returns: TRUE/FALSE + (FALSEなら pc_format_media が必要) + *---------------------------------------------------------------------------*/ +BOOL sdmcCheckMedia( void) +{ + u16 i; + SdmcResultInfo SdResult; + u8* bufp; + u32 buffer[512/4]; + u8 systemid; + + /**/ + 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: sdmcRtfsIo + + Description: 上位層からのセクタリード/ライト要求を受ける + + Arguments: driveno : ドライブ番号 + block : 開始ブロック番号 + buffer : + count : ブロック数 + reading : リード要求時にTRUE + + Returns: TRUE/FALSE + *---------------------------------------------------------------------------*/ +BOOL sdmcRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading) +{ + u16 result; + SdmcResultInfo SdResult; + + 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: sdmcRtfsCtrl + + 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 sdmcRtfsCtrl( int driveno, int opcode, void* pargs) +{ + DDRIVE *pdr; + DEV_GEOMETRY gc; + int heads, secptrack; + + pdr = pc_drno_to_drive_struct( driveno); + + switch( opcode) { + case DEVCTL_GET_GEOMETRY: //formatまたはpartirionするときにRTFSが使うパラメータ + PRINTDEBUG( "DEVCTL_GET_GEOMETRY\n"); + if( (pdr->drive_flags & DRIVE_FLAGS_INSERTED) == 0) { /* 抜かれていた場合 */ + if( SDCARD_OutFlag == TRUE) { /* 今現在も抜かれているとき */ + return( -1); + }else{ /* 今現在は再挿入されているとき */ + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + } + } + + rtfs_memset( &gc, (byte)0, sizeof(gc)); + + 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] = 'C'; + gc.fmt.oemname[1] = 'T'; + gc.fmt.oemname[2] = 'R'; + 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 (pdr->drive_flags & DRIVE_FLAGS_INSERTED) { /* 抜かれてない場合 */ + 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); + } + }else{ /* 抜かれていた場合 */ + if( SDCARD_OutFlag == FALSE) { /* 排出フラグ参照 */ + pdr->drive_flags |= DRIVE_FLAGS_INSERTED; + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + PRINTDEBUG( "DEVTEST_CHANGED\n"); + return( DEVTEST_CHANGED); //挿さっている + }else{ + PRINTDEBUG( "DEVTEST_NOMEDIA\n"); + return( DEVTEST_NOMEDIA); //挿さってない + } + } + + case DEVCTL_WARMSTART: //attachのときしか呼ばれない + PRINTDEBUG( "DEVCTL_WARMSTART\n"); + /*-- GoIdleセット --*/ + if( func_SDCARD_Out != i_sdmcRemovedIntr) { + func_usr_sdmc_out = func_SDCARD_Out; //ユーザコールバック取得 + } + sdmcGoIdle( func_SDCARD_In, i_sdmcRemovedIntr); //カード初期化シーケンス + /*------------------*/ + pdr->drive_flags |= (DRIVE_FLAGS_VALID | DRIVE_FLAGS_REMOVABLE | DRIVE_FLAGS_PARTITIONED); + pdr->partition_number = 0; + + if( SDCARD_OutFlag == FALSE) { /* 排出フラグ参照 */ + pdr->drive_flags |= DRIVE_FLAGS_INSERTED; + }else{ /* カード未挿入のとき */ + pdr->drive_flags &= (~(DRIVE_FLAGS_INSERTED)); //抜かれているだけではVALIDフラグは落とさないらしい + } + 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); +} + +/*---------------------------------------------------------------------------* + 抜取コールバック関数 + + RTFSが次回"DEVCTL_GET_GEOMETRY"を行うとき、ここでセットしたパラメータを知る + *---------------------------------------------------------------------------*/ +void i_sdmcRemovedIntr( void) +{ + DDRIVE *pdr; + + pdr = pc_drno_to_drive_struct( sdmc_drive_no); + if( pdr) { + pdr->dev_table_perform_device_ioctl( pdr->driveno, + DEVCTL_REPORT_REMOVE, + (void*)0); + } + + if( func_usr_sdmc_out) { + func_usr_sdmc_out(); //ユーザコールバック + } +} + + +/*---------------------------------------------------------------------------* + Name: sdmcRtfsAttach + + Description: sdmcドライバをドライブに割り当てる + + Arguments: driveno : ドライブ番号 + + Returns: + *---------------------------------------------------------------------------*/ +BOOL sdmcRtfsAttach( int driveno) +{ + BOOLEAN result; + DDRIVE pdr; + + pdr.dev_table_drive_io = sdmcRtfsIo; + pdr.dev_table_perform_device_ioctl = sdmcRtfsCtrl; + 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, "SD"); //構造体がFSライブラリ側にコピーされる + + /*drivenoをグローバル変数に記憶*/ + sdmc_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)*/ diff --git a/build/libraries/fatfs/ARM7/rom_sdmc/sdif.c b/build/libraries/fatfs/ARM7/rom_sdmc/sdif.c new file mode 100644 index 00000000..e5064952 --- /dev/null +++ b/build/libraries/fatfs/ARM7/rom_sdmc/sdif.c @@ -0,0 +1,1236 @@ +/* + Project: TwlBrom SD Card driver + File: sd_card.c + + 2007, Research and Development Department, Nintendo. +*/ + +#include +//#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 + #define PRINTDEBUG vlink_dos_printf + #endif +#else + #define PRINTDEBUG( ...) ((void)0) +#endif +*/ +// #define PRINTDEBUG OS_TPrintf + #define PRINTDEBUG( ...) ((void)0) + + +#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; /* 現在のポート番号 */ + +/*********************************************************************** + 外部参照変数 +***********************************************************************/ +volatile SDMC_ERR_CODE SDCARD_ErrStatus; /* エラーステータス */ +vu32 SDCARD_Status; /* カードステータス */ +//extern volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ +//extern void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */ + +extern void SDCARD_TimerCheck( void); +extern void SYSFPGA_irq(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) +{ + PRINTDEBUG( "command\n"); + 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 待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if( (SD_INFO2 & SD_INFO2_MASK_ALLERRMASK) != 0) { //IPエラー発生? + SYSFPGA_irq(); + break; + } + if( SDCARD_ErrStatus != 0) { + break; + } + } + + /*ROM版はエラー割り込みが入らないためRES_ENDが立つとエラーを見逃すことがあるので最後にINFO2評価*/ + if( (SD_INFO2 & SD_INFO2_MASK_ALLERRMASK) != 0) { //IPエラー発生? + SYSFPGA_irq(); + } + + 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) +{ +#if 0 + 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{ +#endif + SDCARD_SDHCFlag = FALSE; +#if 0 + } +#endif + 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)待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if( (SD_INFO2 & SD_INFO2_MASK_ALLERRMASK) != 0) { //IPエラー発生? + SYSFPGA_irq(); + break; + } + if( SDCARD_ErrStatus != 0) { + break; + } + } + + /*ROM版はエラー割り込みが入らないためRES_ENDが立つとエラーを見逃すことがあるので最後にINFO2評価*/ + if( (SD_INFO2 & SD_INFO2_MASK_ALLERRMASK) != 0) { //IPエラー発生? + SYSFPGA_irq(); + } + 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割り込み発生 + *---------------------------------------------------------------------------*/ +BOOL 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 待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if( (SD_INFO2 & SD_INFO2_MASK_ALLERRMASK) != 0) { //IPエラー発生? + SYSFPGA_irq(); + break; + } + if( SDCARD_ErrStatus != 0) { + break; + } + } + + /*ROM版はエラー割り込みが入らないためRES_ENDが立つとエラーを見逃すことがあるので最後にINFO2評価*/ + if( (SD_INFO2 & SD_INFO2_MASK_ALLERRMASK) != 0) { //IPエラー発生? + SYSFPGA_irq(); + } + + 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; +} + + diff --git a/build/libraries/fatfs/ARM7/rom_sdmc/sdif_ip.h b/build/libraries/fatfs/ARM7/rom_sdmc/sdif_ip.h new file mode 100644 index 00000000..83e2a67a --- /dev/null +++ b/build/libraries/fatfs/ARM7/rom_sdmc/sdif_ip.h @@ -0,0 +1,349 @@ +/* +** Copyright (c) 2000-2001 Matsushita Electric Industrial Co., Ltd. +** All Rights Reserved. +*/ + +/* +** $Module SDカードアクセスモジュール・インクルード +** $Filename SD_CARD_IP.H +** $Version 1.0 版 +** $Date 01/02/16 +** $Log 01/02/16 rev1.0作成 +** 松下電器産業(株)半導体開発本部 +*/ + + +#ifndef __SD_CARD_IP_H__ +#define __SD_CARD_IP_H__ + +//#define IO3 0 /* Insert Remove SW = FALSE IO3 = TRUE */ + +//#define MAX_SD_CLOCK_4M 0 /* MAX SD Clock 4.608MHz */ +//#define MAX_SD_CLOCK_9M 1 /* MAX SD Clock 9.216MHz */ + + +/*--------------------------------------------- + ラッパーレジスタのビット制御(フラグ定義) +---------------------------------------------*/ +/* SD_CNTレジスタ */ +#define SDIF_CNT_USEDTC (0x0001) /* DTC使用フラグ (R/W) */ +#define SDIF_CNT_USEFIFO (0x0002) /* FIFO使用フラグ (R/W) */ +#define SDIF_CNT_FULL (0x0100) /* FIFO FULLフラグ (RO) */ +#define SDIF_CNT_NEMP (0x0200) /* FIFO NOT EMPTYフラグ (RO) */ +#define SDIF_CNT_FCLR (0x0400) /* FIFO クリアフラグ (WO) */ +#define SDIF_CNT_FFIE (0x0800) /* FIFO FULLで割り込み (R/W) */ +#define SDIF_CNT_FEIE (0x1000) /* FIFO EMPTYで割り込み (R/W) */ + +#define SDCARD_UseFifoFlag ((*SDIF_CNT) & SDIF_CNT_USEFIFO) + +/*------------------------------------- +レジスタのビット制御(フラグ定義) +-------------------------------------*/ +/* SD_CMDレジスタ*/ +#define SD_CMD_CMD 0x0000 /* SDカードへの通常アクセス(CMD) */ +#define SD_CMD_ACMD 0x0040 /* SDカードへのセキュリティアクセス(ACMD) */ + +/* SD_STOPレジスタ */ +#define SD_STOP_STP 0x0001 /* データ転送終了を知らせる */ +#define SD_STOP_SEC_ENABLE 0x0100 /* SD_SECCNTレジスタ有効(セクタカウントレジスタ) */ + +/* SD_SECCNTレジスタ */ +#define SD_SECCNT_END 0x0000 /* SD_SECCNTレジスタ カウントチェック */ + +/* SD_SIZEレジスタ */ +#define SD_SIZE_DATA_LENGTH_1B 0x0001 /* SDカード転送データサイズ 1Bytes */ +#define SD_SIZE_DATA_LENGTH_2B 0x0002 /* SDカード転送データサイズ 2Bytes */ +#define SD_SIZE_DATA_LENGTH_4B 0x0004 /* SDカード転送データサイズ 4Bytes */ +#define SD_SIZE_DATA_LENGTH_8B 0x0008 /* SDカード転送データサイズ 8Bytes (SCR) */ +#define SD_SIZE_DATA_LENGTH_16B 0x0010 /* SDカード転送データサイズ 16Bytes */ +#define SD_SIZE_DATA_LENGTH_32B 0x0020 /* SDカード転送データサイズ 32Bytes */ +#define SD_SIZE_DATA_LENGTH_64B 0x0040 /* SDカード転送データサイズ 64Bytes (SD_Status) */ +#define SD_SIZE_DATA_LENGTH_128B 0x0080 /* SDカード転送データサイズ 128Bytes */ +#define SD_SIZE_DATA_LENGTH_256B 0x0100 /* SDカード転送データサイズ 256Bytes */ +#define SD_SIZE_DATA_LENGTH_512B 0x0200 /* SDカード転送データサイズ 512Bytes (データ) */ + +/* SD_OPTIONレジスタ */ +#define SD_OPTION_WIDTH_1BIT 0x8000 /* ビット幅の選択 1bit幅 */ +#define SD_OPTION_MSEL_C2NOUSE 0x4000 /* C2モジュール未使用 */ +#define SD_CD_DETECT_TIME 0xFFF0 /* CD 検出タイムだけをクリアするためのマスク */ + +/* SD_INFO2レジスタ */ +#define SD_INFO2_ERR_ILA 0x8000 /* イリーガルアクセスエラー */ +#define SD_INFO2_BWE 0x0200 /* SDカードから512byteのデータ書込み要求 */ +#define SD_INFO2_BRE 0x0100 /* SDカードから512byteのデータ読込み要求 */ +#define SD_INFO2_ERR_ALLCLR 0x807F /* SD Card エラーレジスタクリア */ +#define SD_INFO2_ERR_SDDAT0 0x0080 /* SD Card Busy bit */ +#define SD_INFO2_ERR_RESTIMEOUT 0x0040 /* レスポンスタイムアウトエラー */ +#define SD_INFO2_ERR_UNDERFLOW 0x0020 /* FIFO アンダーフローエラー */ +#define SD_INFO2_ERR_OVERFLOW 0x0010 /* FIFO オーバーフローエラー */ +#define SD_INFO2_ERR_TIMEOUT 0x0008 /* レスポンス以外のタイムアウトエラー */ +#define SD_INFO2_ERR_END 0x0004 /* フレーム終了認識できないときの(END)エラー */ +#define SD_INFO2_ERR_CRC 0x0002 /* CRC エラー */ +#define SD_INFO2_ERR_CMD 0x0001 /* CMDエラー */ + +#define SD_INFO2_RW_SET 0x0300 /* SDカード Read/Write 要求割込み要因チェック */ +#define SD_INFO2_ERROR_SET 0x807F /* SDカード エラー割込み要因チェック */ + +/* SD_INFO2_MASKレジスタ */ +#define SD_INFO2_MASK_ILA 0x8000 /* イリーガルアクセスエラー割込みマスク */ +#define SD_INFO2_MASK_BWE 0x0200 /* SDカードからのデータ書込み要求割込み禁止 */ +#define SD_INFO2_MASK_BRE 0x0100 /* SDカードからのデータ読込み要求割込み禁止 */ +#define SD_INFO2_MASK_ALLERRMASK 0x807F /* 全エラー割り込み禁止 */ +#define SD_INFO2_MASK_EXCEPT_OVERFLOW 0x802F /* 全エラー割り込み禁止 FIFO Overflow Errorを除く */ +#define SD_INFO2_MASK_RESTIMEOUT 0x0040 /* Time out 割込みEnable */ +#define SD_INFO2_MASK_UNDERFLOW 0x0020 /* FIFO アンダーフロー 割込みEnable */ +#define SD_INFO2_MASK_OVERFLOW 0x0010 /* FIFO オーバーフロー 割込みEnable */ +#define SD_INFO2_MASK_TIMEOUT 0x0008 /* Time out 割込みEnable */ +#define SD_INFO2_MASK_END 0x0004 /* END エラー 割込みEnable */ +#define SD_INFO2_MASK_CRC 0x0002 /* CRC エラー 割込みEnable */ +#define SD_INFO2_MASK_CMD 0x0001 /* CMD エラー 割込みEnable */ +#define SD_INFO2_MASK_ERRSET 0x807F /* SDカード エラー割込み要因チェック */ + +/* SD_INFO1レジスタ */ +#define SD_INFO1_DAT3DETECT 0x0400 /* (IO3検出) card detect(検出=1) : CTRでは使用できない*/ +#define SD_INFO1_DAT3INSERT 0x0200 /* (IO3検出) card inserted(挿入=1) : CTRでは使用できない */ +#define SD_INFO1_DAT3REMOVE 0x0100 /* (IO3検出) card removed(抜け=1) : CTRでは使用できない */ +#define SD_INFO1_DAT3INIT 0x0300 /* (IO3検出) の初期化 */ +#define SD_INFO1_WRITEPROTECT 0x0080 /* write protect(書き込み禁止=1) */ +#define SD_INFO1_DETECT 0x0020 /* card detect(検出=1) */ + +#define SD_INFO1_INSERT 0x0010 /* card inserted(挿入=1) */ +#define SD_INFO1_REMOVE 0x0008 /* card removed(抜け=1) */ + +#define SD_INFO1_ALL_END 0x0004 /* R/W access all end */ +#define SD_INFO1_RES_END 0x0001 /* Response end */ +#define SD_INFO1_INIT 0x0005 /* SD Cardの状態を初期化 */ + +#define SD_INFO1_SET 0x031D /* SDカード 挿抜 and RWアクセス終了 and レスポンス終了 要求割込み要因チェック */ + +/* SD_INFO1_MASKレジスタ (0:割り込み許可、1:割り込み禁止)*/ +#define SD_INFO1_MASK_DAT3INSERT 0x0200 /* (IO3検出) card inserted(挿入) 割込み禁止 */ +#define SD_INFO1_MASK_DAT3REMOVE 0x0100 /* (IO3検出) card removed(抜け) 割込み禁止 */ +#define SD_INFO1_MASK_INSERT 0x0010 /* card inserted(挿入) 割込み禁止 */ +#define SD_INFO1_MASK_REMOVE 0x0008 /* card removed(抜け) 割込み禁止 */ +#define SD_INFO1_MASK_ALL_END 0x0004 /* R/W access all end 割込み禁止 */ +#define SD_INFO1_MASK_RES_END 0x0001 /* Response end 割込み禁止 */ + +/* CC_EXT_MODEレジスタ */ +#define CC_EXT_MODE_PIO 0x0000 /* PIOモード */ +#define CC_EXT_MODE_DMA 0x0002 /* DMAモード */ + +/* SOFT_RSTレジスタ */ +#define SOFT_RST_SDIF_RST 0x0001 /* SD I/Fモジュールをリセット */ + +/* SD_CLK_CTRLレジスタ */ +#define SD_CLK_CTRL_SDCLKEN 0x0100 /* SDカードクロック出力イネーブル */ +#define SD_CLK_CTRL_512 0x0180 /* SDクロックの周波数(分周比512)*/ +#define SD_CLK_CTRL_256 0x0140 /* SDクロックの周波数(分周比256)*/ +#define SD_CLK_CTRL_128 0x0120 /* SDクロックの周波数(分周比128)*/ +#define SD_CLK_CTRL_64 0x0110 /* SDクロックの周波数(分周比 64)*/ +#define SD_CLK_CTRL_32 0x0108 /* SDクロックの周波数(分周比 32)*/ +#define SD_CLK_CTRL_16 0x0104 /* SDクロックの周波数(分周比 16)*/ +#define SD_CLK_CTRL_8 0x0102 /* SDクロックの周波数(分周比 8)*/ +#define SD_CLK_CTRL_4 0x0101 /* SDクロックの周波数(分周比 4)*/ +#define SD_CLK_CTRL_2 0x0100 /* SDクロックの周波数(分周比 2)*/ + + +/*------------------------------------- +マルチポート対応ビット制御(フラグ定義) +-------------------------------------*/ +#define SDCARD_PORT_NO 0x0300 /* カードポート選択数 */ +#define SDCARD_PORT_NO_MAX 0x04//0x02 /* カードポート最大選択数 */ +#define SDCARD_PORT_NO_MIN 0x01 /* カードポート最小選択数 */ +#define SDCARD_PORT_SELECT_NO 0x0001 /* カードポート番号ビット */ +#define SDCARD_PORT0 0x0000 /* カードポート番号ビット */ +#define SDCARD_PORT1 0x0001 /* カードポート番号ビット */ + +/* EXT_WPレジスタ(ポート1以降のライトプロテクト) */ +#define EXT_WP_PORT1 0x0001 /* ポート1write protect(書き込み禁止=1)*/ + +/* EXT_CDレジスタ */ +#define EXT_CD_PORT1_REMOVE 0x0001 /* ポート1 card detect(検出=1) */ +#define EXT_CD_PORT1_INSERT 0x0002 /* ポート1 card inserted(挿入=1) */ +#define EXT_CD_PORT1_DETECT 0x0004 /* ポート1 card removed(抜け=1) */ + +/* EXT_CD_DAT3レジスタ */ +//#define EXT_CD_PORT1_DAT3INIT 0x0003 /* ポート1 card の状態 (IO3検出) の初期化 */ +#define EXT_CD_PORT1_DAT3REMOVE 0x0001 /* ポート1 dat3 card detect(検出=1) */ +#define EXT_CD_PORT1_DAT3INSERT 0x0002 /* ポート1 dat3 card inserted(挿入=1) */ +#define EXT_CD_PORT1_DAT3DETECT 0x0004 /* ポート1 dat3 card removed(抜け=1) */ + +/* EXT_CD_DAT3_MASKレジスタ */ +#define EXT_CD_MASK_PORT1INSERT 0x0002 /* port1 card inserted(挿入) 割込み禁止 */ +#define EXT_CD_MASK_PORT1REMOVE 0x0001 /* port1 card removed(抜け) 割込み禁止 */ +#define EXT_CD_MASK_PORT1DAT3INSERT 0x0002 /* port1 (IO3検出) card inserted(挿入) 割込み禁止 */ +#define EXT_CD_MASK_PORT1DAT3REMOVE 0x0001 /* port1 (IO3検出) card removed(抜け) 割込み禁止 */ + +/*------------------------------------- +カードの選択 +--------------------------------------*/ +#define SDCARD_DETECT_VISUAL_BIT 0x0400 /*** upper layer card detected visual bit ***/ + +/*------------------------------------- +ライトプロテクト +-------------------------------------*/ +#define SDCARD_WP_PERMANENT_BIT 0x0020 /*** permanent write protection ***/ +#define SDCARD_WP_TEMPORARY_BIT 0x0010 /*** temporary write protection ***/ + +/*------------------------------------- +SD or MMCカードコマンド +-------------------------------------*/ +#define GO_IDLE_STATE (0) /* resets all cards to idle state */ +#define SEND_OP_COND (1) /* Asks all cards in idle state to send their operation conditions */ +#define ALL_SEND_CID (2) /* send CID numbers */ +#define SEND_RELATIVE_ADDR (3) /* ask the card to publish a new relative address(RCA) */ +#define SET_BUS_WIDTH (6) /* ビット幅の選択 */ +#define SELECT_CARD (7) /* Command toggles acard between thr Stand-by and Transfer states */ +#define SEND_CSD (9) /* addressed card sends its card-specific data(CSD) */ +#define STOP_TRANSMISSION (12) /* forces the card to stop transmission */ +#define SD_SEND_STATUS (13) /* addressed card sends its status register */ +#define SET_BLOCKLEN (16) /* sets the block length */ +#define READ_MULTIPLE_BLOCK (18) /* マルチブロックリード */ +#define WRITE_MULTIPLE_BLOCK (25) /* マルチブロックライト */ +#define APP_CMD (55) /* CMD55 */ +#define SD_STATUS (13) /* ACMD13 Send the SD_CARD status */ +#define SEND_NUM_WR_SECTORS (22) /* ACMD22 書きこみ完了セクタ数取得 */ +#define SD_APP_OP_COND (41) /* ACMD41 */ +#define SEND_SCR (51) /* SD configuration register (SCR) */ + +/* MMCplus, eMMCの定義 */ +#define EXT_CSD_ACCESS (6) + +/* Extended Commandの定義 */ +#define EXT_NORMAL (0) +#define EXT_SDIO (0x4000) + +#define EXT_COM_R3 (0x0700) + +#define EXT_CMD (0x00C0) + +#define SEND_IF_COND (8) /* Physical Layer 2.0 で追加されたコマンド */ +#define SEND_IF_COND_EXT (EXT_SDIO | EXT_COM_R3 | EXT_CMD | SEND_IF_COND) + + +/*------------------------------------- +IP レジスタアクセス マクロ関数 +-------------------------------------*/ +#define SD_OrFPGA(reg,value) ((reg) |= (value)); +#define SD_AndFPGA(reg,value) ((reg) &= (value)); +#define SD_SetFPGA(reg,value) ((reg) = (value)); +#define SD_GetFPGA(dest,reg) ((dest) = (reg)); + +/*********************************************************************** + 構造体定数 +***********************************************************************/ +typedef union{ + u32 dat; + struct { + u16 low; + u16 high; + } dt2word; +} LELONG; + +/*------------------------------------- +その他(ビット制御) +-------------------------------------*/ +#define RSP_R3_OCR31 0x8000 /* Use OCR Busy bit Check */ +#define RSP_R3_OCR_VDD 0x0030 /* Use OCR VDD bit Check (3.2-3.3v,3.3-3.4v is OK)*/ + +/*--- SCR[0]に対する4bitバス幅対応フラグのマスク ---*/ +//SCRのbit50に相当するが、SCRとSD_STATUSはMSBから送られてくることを考慮してある +#define SCR_DAT_BUS_WIDTH_4BIT 0x0400 /* SCR DAT Bus width supported 4bit */ + +/*--- 127bitCSD (CSD[0]〜CSD[7])関連 ---*/ +#define CSD_VDD_R_CURR_MIN 0x0038 /* "VDD_R_CURR_MIN" (for CSD[3]) */ +#define CSD_VDD_R_CURR_MAX 0x0007 /* "VDD_R_CURR_MAX" (for CSD[3]) */ +#define CSD_VDD_W_CURR_MIN 0xE000 /* "VDD_W_CURR_MIN" (for CSD[2]) */ +#define CSD_VDD_W_CURR_MAX 0x1C00 /* "VDD_W_CURR_MAX" (for CSD[2]) */ + +#define CSD_READ_BL_LEN 0x0F00 /* "READ_BL_LEN" (for CSD[4])*/ +#define CSD_WRITE_BL_LEN_BIT_25_24 0x0003 /* "WRITE_BL_LEN" (for CSD[1])*/ +#define CSD_WRITE_BL_LEN_BIT_23_22 0xC000 /* "WRITE_BL_LEN" (for CSD[0]*/ +#define CSD_READ_BL_PARTIAL 0x0080 /* "READ_BL_PARTIAL" (for CSD[4]) */ +#define CSD_TRANSFER_RATE 0x0700 /* "Transfer rate unit" of "TRAN_SPEED" (for CSD[5]) */ +#define CSD_TRAN_SPEED_100K 0x0000 /* 100Kbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_1M 0x0001 /* 1Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_10M 0x0002 /* 10Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_100M 0x0003 /* 100Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_OTHER 0x0004 /* Reserve (for CSD Transfer rate) */ + +#define CSD_C_SIZE_MULT 0x0380 /* RSP2 の bit[49:47] */ +#define CSD_C_SIZE_BIT_73_72 0x0003 /* RSP3 の bit[73:72](C_SIZE) */ +#define CSD_C_SIZE_BIT_71_62 0xFFC0 /* RSP3 の bit[71:62](C_SIZE) */ +//SDHC(CSD format version2)の場合 +#define CSD_C_SIZE_BIT_69_56 0x3FFF /* SD_CSD[3] */ +#define CSD_C_SIZE_BIT_55_48 0xFF00 /* SD_CSD[2] */ + +#define CSD_STRUCT_BIT_127_126 0x00C0 /* SD_CSD[7] */ + +//#define VDD_R_CURR_MIN 0x0000 /* CSD max read current@VDD min */ +//#define VDD_R_CURR_MAX 0x0007 /* CSD max read current@VDD max */ +//#define VDD_W_CURR_MIN 0x0000 /* CSD max write current@VDD min */ +//#define VDD_W_CURR_MAX 0x0007 /* CSD max write current@VDD max */ + +/*--- R1レスポンスの card status(32bit)に対するマスク ---*/ +#define RSP_R1_STATUS_ERR 0xF9FF0008 /* R1(レスポンス)のカードステータスのチェック */ +#define SDCARD_STATUS_OUT_OF_RANGE 0x80000000 /* Card Status OUT_OF_RANGE のチェック */ +#define RSP_R1_CURRENT_STATE 0x1E00 /* CARD current state */ +/*-------------------------------------------------------*/ + +/* レスポンスのRSP0 & RSP_R1_CURRENT_STATEを1ビット右シフトした値に対するフラグ */ +#define CURRENT_STATE_DATA 0x0500 /* CARD current state data */ +#define CURRENT_STATE_RCV 0x0600 /* CARD current state rcv */ + +/* カードステータス */ +#define SD_MEMORY_CARD 0x00FF /* SD_CARD_TYPE SD memory card */ + + +/*------------------------------------- +プロトタイプ宣言 +-------------------------------------*/ +void SD_Init(void); /* SD Cardインターフェース部をリセット&初期設定 */ +void SD_EnableInfo(void); /* SD Card 挿抜 割り込みイネーブル・ディスエーブル */ +u16 SD_Command(u16 ucCommand); /* SDカードコマンド送出 */ +u16 SD_AppCommand(void); /* SDカード RCA = 1をセット後 CMD55 発行 */ +u16 SD_AppOpCond(void); /* ACMD41 発行 busyでなくなるまで繰り返し */ +u16 SD_SendOpCond(void); /* CMD1 発行 busyでなくなるまで繰り返し */ +u16 SD_SendIfCond(void); /* CMD8 発行 (SDHCのみ反応してくる) */ +u16 SD_SendRelativeAddr(void); /* CMD3 発行 正常終了時 RCA<-ResのRCA */ +u16 SD_SelectCard(void); /* CMD7 発行 Command toggles acard between the Stand-by and Transfer states */ +u16 SD_SetBlockLength(u32 ulBlockLength); /* ブロックレングス(1セクタの転送量)の設定 */ +u16 SD_SendCID(void); /* card identification data の取得コマンド発行 */ +u16 SD_SendCSD(void); /* card-specific data の取得コマンド発行 */ +u16 SD_SendSCR(void); /* SD register の取得コマンド発行 */ +u16 SD_SDStatus(void); /* SD STATUS の取得コマンド発行 */ +u16 SD_SendStatus(void); /* SD status register の取得コマンド発行 */ +u16 SD_MultiReadBlock(u32 ulOffset); /* マルチセクタリードコマンド発行 */ +u16 SD_ClockDivSet(u16 usTranSpeed); /* カードの動作クロック設定 */ + +void SD_EnableClock( void); /* SDカードのクロック有効 */ +void SD_DisableClock( void); /* SDカードのクロック無効(省電力) */ + +u16 SD_SelectBitWidth(s16 b4bit); /* ビット幅の選択 */ + +u16 MMCP_WriteBusWidth(s16 b4bit); +u16 MMCP_BusTest( BOOL readflag); + + +BOOL SD_FPGA_irq(void); /* カード転送要求時のFPGAの制御 */ +void SD_StopTransmission(void); /* カード転送終了をFPGAに通知する。 */ +void SD_TransEndFPGA(void); /* カード転送の終了処理(割り込みマスクを戻す) */ +u16 SD_CheckStatus(BOOL bRead); /* Normal response command カードステータスのチェック */ +u16 SD_SwapByte(u16 *data); /* 上位byte、下位byteを入れ替える関数 */ + +void SD_EnableSeccnt( u32 ulSDCARD_SectorCount); /* SD_SECCNTレジスタ有効化&値設定 */ +void SD_DisableSeccnt( void); /* SD_SECCNTレジスタ無効化 */ + +void SD_SetErr(u16 Error); /* エラーステータスを設定する */ +void SD_ClrErr(u16 Error); /* エラーステータスをクリアする */ + +BOOL SD_CheckFPGAReg(u16 reg,u16 value); /* IPレジスタにフラグが立っているか判定 */ + +void SD_TransReadyFPGA(void); /* 転送処理準備FPGA設定 */ +u16 SD_TransCommand(u16 ucCommand); /* 命令発行処理 */ + +u16 SD_MultiWriteBlock(u32 ulOffset); /* マルチセクタライトコマンド発行 */ +u16 SD_SendNumWRSectors(void); /* ACMD22 書きこみ完了セクタ数取得コマンド発行 */ + + +#endif /* __SD_CARD_IP_H__ */ diff --git a/build/libraries/fatfs/ARM7/rom_sdmc/sdif_reg.h b/build/libraries/fatfs/ARM7/rom_sdmc/sdif_reg.h new file mode 100644 index 00000000..a5f4f862 --- /dev/null +++ b/build/libraries/fatfs/ARM7/rom_sdmc/sdif_reg.h @@ -0,0 +1,118 @@ +/*---------------------------------------------------------------------------* + Project: TwlBrom - SD driver + File: sd_ip_reg.h + + Copyright 2006 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. + *---------------------------------------------------------------------------*/ + +#ifndef __SD_IP_REG_H__ +#define __SD_IP_REG_H__ + +/********************************************* + SD IPレジスタ + + (R/W) : readable and writable + (RO) : read only +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define SD_IP_BASE (0x08030000) // NTR用ブレッドボード設定 +#else +#define SD_IP_BASE (0x400B0000) // IOP実機設定 +#endif*/ +#define SD_IP_BASE (0x04004800) // TWL ARM7設定 + + +#define SD_CMD (*(vu16 *)(SD_IP_BASE + 0x00)) /* CMD発行レジスタ(R/W) */ +#define SD_PORTSEL (*(vu16 *)(SD_IP_BASE + 0x02)) /* ポート選択レジスタ(R/W) */ +#define SD_ARG0 (*(vu16 *)(SD_IP_BASE + 0x04)) /* Argument[15:0] (R/W) */ +#define SD_ARG1 (*(vu16 *)(SD_IP_BASE + 0x06)) /* Argument[31:16] (R/W) */ +#define SD_STOP (*(vu16 *)(SD_IP_BASE + 0x08)) /* 転送終了後STOP、SD_SECCNT有効 (R/W) */ +#define SD_SECCNT (*(vu16 *)(SD_IP_BASE + 0x0A)) /* 転送セクタ数制御 (R/W) */ +#define SD_RSP0 (*(vu16 *)(SD_IP_BASE + 0x0C)) /* Response [23:8] (RO) */ +#define SD_RSP1 (*(vu16 *)(SD_IP_BASE + 0x0E)) /* Response [39:24] (RO) */ +#define SD_RSP2 (*(vu16 *)(SD_IP_BASE + 0x10)) /* Response [55:40] (RO) */ +#define SD_RSP3 (*(vu16 *)(SD_IP_BASE + 0x12)) /* Response [71:56] (RO) */ +#define SD_RSP4 (*(vu16 *)(SD_IP_BASE + 0x14)) /* Response [87:72] (RO) */ +#define SD_RSP5 (*(vu16 *)(SD_IP_BASE + 0x16)) /* Response [103:88] (RO) */ +#define SD_RSP6 (*(vu16 *)(SD_IP_BASE + 0x18)) /* Response [119:104] (RO) */ +#define SD_RSP7 (*(vu16 *)(SD_IP_BASE + 0x1A)) /* Response [127:120] (RO) */ +#define SD_INFO1 (*(vu16 *)(SD_IP_BASE + 0x1C)) /* SDメモリーカードの状態 (R/W) */ +#define SD_INFO2 (*(vu16 *)(SD_IP_BASE + 0x1E)) /* バッファ制御とエラー情報 (R/W) */ +#define SD_INFO1_MASK (*(vu16 *)(SD_IP_BASE + 0x20)) /* SD_INFO1割込みマスク (R/W) */ +#define SD_INFO2_MASK (*(vu16 *)(SD_IP_BASE + 0x22)) /* SD_INFO2割込みマスク (R/W) */ +#define SD_CLK_CTRL (*(vu16 *)(SD_IP_BASE + 0x24)) /* SDクロック設定 (R/W) */ +#define SD_SIZE (*(vu16 *)(SD_IP_BASE + 0x26)) /* ビット幅と転送データ長の設定 (R/W) */ +#define SD_OPTION (*(vu16 *)(SD_IP_BASE + 0x28)) /* タイムアウト、width、CD検出タイム (R/W) */ +#define SD_ERR_STS1 (*(vu16 *)(SD_IP_BASE + 0x2C)) /* CMD, CRC, ENDエラー割込み原因 (RO) */ +#define SD_ERR_STS2 (*(vu16 *)(SD_IP_BASE + 0x2E)) /* タイムアウトエラー割込み原因 (RO) */ +#define SD_BUF0 (vu16 *)(SD_IP_BASE + 0x30) /* SDバッファ読込/書込データポート (R/W) */ +#define CC_EXT_MODE (*(vu16 *)(SD_IP_BASE + 0xD8)) /* DMAモード/PIOモード切り替え */ +#define SOFT_RST (*(vu16 *)(SD_IP_BASE + 0xE0)) /* ソフトウェアリセット (R/W) */ +#define VERSION (*(vu16 *)(SD_IP_BASE + 0xE2)) /* Version レジスタ (RO) */ +#define EXT_WP (*(vu16 *)(SD_IP_BASE + 0xF6)) /* 拡張SD Card ライトプロテクト (RO) */ +#define EXT_CD (*(vu16 *)(SD_IP_BASE + 0xF8)) /* 拡張SD Card 検出、挿入、抜け フラグ (R/W) */ +#define EXT_CD_DAT3 (*(vu16 *)(SD_IP_BASE + 0xFA)) /* 拡張SD Card 検出、挿入、抜け フラグ (R/W) */ +#define EXT_CD_MASK (*(vu16 *)(SD_IP_BASE + 0xFC)) /* 拡張SD Card 検出、挿入、抜け 割込みマスク (R/W) */ +#define EXT_CD_DAT3_MASK (*(vu16 *)(SD_IP_BASE + 0xFE)) /* 拡張SD Card 検出、挿入、抜け 割込みマスク (R/W) */ + + + +/********************************************* + SD I/F(ラッパー)レジスタ +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define SD_IF_BASE (0x08030100) // NTR用ブレッドボード設定 +#else +#define SD_IF_BASE (0x400B0100) // IOP実機設定 +#endif*/ +#define SD_IF_BASE (0x04004900) // IOP実機設定 + + +#define SDIF_CNT ((vu32 *)(SD_IF_BASE+0x00)) /* コントロール */ +#define SDIF_FDS ((vu32 *)(SD_IF_BASE+0x04)) /* FIFOサイズ */ +#define SDIF_FSC ((vu32 *)(SD_IF_BASE+0x08)) /* セクタカウント */ +#define SDIF_FI ((vu32 *)(SD_IF_BASE+0x0c)) /* FIFOウィンドウ */ + +#define SDIF_CNT_L ((vu16 *)(SD_IF_BASE+0x00)) +#define SDIF_CNT_H ((vu16 *)(SD_IF_BASE+0x02)) +#define SDIF_FDS_L ((vu16 *)(SD_IF_BASE+0x04)) +#define SDIF_FDS_H ((vu16 *)(SD_IF_BASE+0x06)) +#define SDIF_FSC_L ((vu16 *)(SD_IF_BASE+0x08)) +#define SDIF_FSC_H ((vu16 *)(SD_IF_BASE+0x0a)) +#define SDIF_FI_L ((vu16 *)(SD_IF_BASE+0x0c)) +#define SDIF_FI_H ((vu16 *)(SD_IF_BASE+0x0e)) + + + +/********************************************* + INTCレジスタ +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define CTR_INT_BASE (0x08000000) +#else +#define CTR_INT_BASE (0x40010000) +#endif + + +#define CTR_INT_SE (CTR_INT_BASE + 0x00) //割り込み要求選択レジスタ +#define CTR_INT_IE (CTR_INT_BASE + 0x04) //IE +#define CTR_INT_IF (CTR_INT_BASE + 0x08) //IF + +#define CTR_IE_SD_MASK (1<<13) //SD割り込みフラグ +*/ +#define CTR_INT_BASE (0x04000000) + +#define CTR_INT_SE (CTR_INT_BASE + 0x208) //割り込み要求選択レジスタ +#define CTR_INT_IE (CTR_INT_BASE + 0x218) //IE +#define CTR_INT_IF (CTR_INT_BASE + 0x21C) //IF + +#define CTR_IE_SD_MASK (1<<8) //SD割り込みフラグ + + +#endif /* __SD_IP_REG_H__ */ diff --git a/build/libraries/fatfs/ARM7/rom_sdmc/sdmc.c b/build/libraries/fatfs/ARM7/rom_sdmc/sdmc.c new file mode 100644 index 00000000..5ec06979 --- /dev/null +++ b/build/libraries/fatfs/ARM7/rom_sdmc/sdmc.c @@ -0,0 +1,2861 @@ +/* + Project: TwlBrom SD port driver + File: sdmc.c + + 2006-2007, Research and Development Department, Nintendo. +*/ + +#include "sdmc.h" +#include "sdif_ip.h" +#include "sdif_reg.h" +#include "sdmc_config.h" +#include + +//#include +//#include "sdmc_config.h" +//#include "sdif_reg.h" /* IP 対応レジスタ定義 */ + //TODO:現状include/firmのほうからsdmc.hをひっぱってきている +//#include +//#include "sdif_ip.h" /* IP 対応フラグ定義 */ + +/*#if (SD_DEBUG_PRINT_ON == 1) + #if (CTR_DEF_ENVIRONMENT_DSEMU == 1) + #define PRINTDEBUG osTPrintf + #else + #include + #define PRINTDEBUG vlink_dos_printf + #endif +#else + #define PRINTDEBUG( ...) ((void)0) +#endif*/ +// #define PRINTDEBUG OS_TPrintf + #define PRINTDEBUG( ...) ((void)0) + + +/*********************************************************************** + 定数 +***********************************************************************/ +#define SD_OPERATION_INIT (0) +#define SD_OPERATION_READ (1) +#define SD_OPERATION_READ_WITH_FIFO (2) +#define SD_OPERATION_WRITE (3) +#define SD_OPERATION_WRITE_WITH_FIFO (4) +#define SD_OPERATION_READ_WITH_FIFO_STREAM_BEGIN (5) +#define SD_OPERATION_READ_WITH_FIFO_STREAM_END (6) + + +/*********************************************************************** + extern変数 +***********************************************************************/ +static u32 sdmc_dma_no; + +/*********************************************************************** + global変数 +***********************************************************************/ +static BOOL sdmc_tsk_created = FALSE; +static u16 sdmc_base_tick; +static u32 sdmc_timeout_ms; + + +/* drsdmc.cでも参照 */ +static SdmcSpec sdmc_current_spec; //TODO:ポート切り替え時、Port0とPort1に保存するように + +typedef struct { //OSMessage + void* buf; + u32 bufsize; + u32 offset; + void (*func)(void); + SdmcResultInfo* info; + u32 operation; + void (*func2)(void); +} SDCARDMsg; + + +/*********************************************************************** + static関数の宣言 +***********************************************************************/ +static SDMC_ERR_CODE i_sdmcSavePortContext( SDPortContext* buf_adr, u16 port_no); +static SDMC_ERR_CODE i_sdmcLoadPortContext( SDPortContext* buf_adr, u16* port_no); + +static void SDCARD_Backup_port0(void); +static void SDCARD_Backup_port1(void); +static void SDCARD_Restore_port0(void); +static void SDCARD_Restore_port1(void); + +static SDMC_ERR_CODE SDCARDi_ReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +static SDMC_ERR_CODE SDCARDi_WriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info); + +static SDMC_ERR_CODE SDCARDi_Read(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +static SDMC_ERR_CODE SDCARDi_ReadBegin(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +static SDMC_ERR_CODE SDCARDi_ReadEnd( BOOL library_flag); +static SDMC_ERR_CODE SDCARDi_Write(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info); + +int MMCP_SetBusWidth( BOOL b4bit); /* ビット幅の選択(MMCplus, eMMC, moviNAND) */ + +static SDMC_ERR_CODE SDCARD_Thread( SDCARDMsg* SdMsg); //SDスレッド +static void SDCARD_Intr_Thread( void* arg); //SD割り込み処理スレッド + +SDMC_ERR_CODE sdmcGoIdle( void (*func1)(),void (*func2)()); +static SDMC_ERR_CODE i_sdmcInit( void); +static SDMC_ERR_CODE SDCARD_Layer_Init(void); +static SDMC_ERR_CODE i_sdmcMPInit( void); /* カードドライバ初期化(マルチポート対応) */ + +static u16 i_sdmcErrProcess(void); /* エラー時の処理 */ +static u16 i_sdmcGetResid(u32 *pResid); /* 書きこみ完了セクタ数の取得 */ +static u16 i_sdmcCheckWP(void); /* SDCARD ライトプロテクトチェック */ + +static void i_sdmcEnable( void); /* SD使用のためのOS準備 */ +static void i_sdmcDisable( void); + +static u16 i_sdmcSendSCR(void); /* SCRの読み出し */ +static u16 SDCARD_SD_Status(void); /* SD_STATUSの取得 */ +static u32 SDCARD_GetR1Status(void); /* Normal response command カードステータスを取得 */ + +static void SDCARD_Dmy_Handler( void); /* 何もしない */ + +void SDCARD_Timer_irq(void* arg); /* タイムアウト割り込みハンドラ */ + +static void SDCARD_irq_Handler( void); /* SD-IPからの割り込みハンドラ */ +static void SDCARD_FPGA_irq(void); /* カードリードライト割り込み処理 */ +static void SDCARD_ATC0_irq(void); /* ATC0転送完了割り込み処理 */ +void SYSFPGA_irq(void); /* SYSFPGAエラー割り込み処理 */ + +void SDCARD_TimerCheck( void); +/*ポート1は無線固定なのでポート選択関数は公開しない*/ +//u16 sdmcSelectedNo(void); /* カードポートの選択 */ +//u16 sdmcSelect(u16 select); /* 現在のカードポート番号のチェック */ + + + + +/*********************************************************************** + 外部参照変数 +***********************************************************************/ +void SDCARD_TimerStart(u32 tim); /* タイムアウト計測スタート */ +void SDCARD_TimerStop(void); /* タイムアウト計測停止 */ + +extern u16 SD_CID[8]; /* CID値保存用 */ +extern u16 SD_CSD[8]; /* CSD値保存用 */ +extern u16 SD_OCR[2]; /* OCR値保存用 */ +extern u16 SD_SCR[4]; /* SCR値保存用 */ +extern u16 SD_RCA; /* RCA値保存用 */ + +extern s16 SDCARD_MMCFlag; /* MMCカードフラグ */ +extern s16 SDCARD_SDHCFlag; /* SDHCカードフラグ */ +extern u16 SD_port_number; /* 現在ポート番号 */ + + +/*********************************************************************** + グローバル +***********************************************************************/ +static u16 SD_SDSTATUS[32]; /* SD_STATUSレジスタ保存用 */ +static u16 SDCARD_WP_FLAG0; /* カードライトプロテクトフラグ。0=なし、1=有り */ +static u16 SDCARD_WP_FLAG1; /* カードライトプロテクトフラグ。0=なし、1=有り */ +static u16 SDCARD_WP_PERMANENT; /* カードライトプロテクト永久フラグ。0=なし、1=有り */ +static u16 SDCARD_WP_TEMPORARY; /* カードライトプロテクト一時フラグ。0=なし、1=有り */ + +static u16* pSDCARD_BufferAddr; /* 保存用データ格納バッファアドレス */ + +static BOOL SDCARD_STREAM_FLAG = FALSE; +static sdmcTransferFunction SDCARD_USR_TRANSFER_FUNC = NULL; /* ユーザ転送関数 */ +//sdmcTransferFunction CURRENT_TRANSFER_FUNC; /* カレント転送関数 */ + +static BOOL SDCARD_DataFlag; /* データフラグ(転送種別) */ +static u32 ulSDCARD_SectorCount; /* 転送セクタ数 */ +static u32 ulSDCARD_RestSectorCount; /* 残り転送セクタ数 */ +static u32 SDCARD_SectorSize; /* セクタサイズ デフォルト 512bytes */ + +static u16 SD_INFO1_VALUE; /* SD_INFO1レジスタ取得用変数 */ +static u16 SD_INFO1_MASK_VALUE; /* SD_INFO1割込みマスク用変数(0で許可, 1で禁止) */ +static u16 SD_INFO2_VALUE; /* SD_INFO2レジスタ取得用変数 */ +static u16 SD_INFO2_MASK_VALUE; /* SD_INFO2割り込みマスク用変数(0で許可, 1で禁止) */ +static u16 SD_INFO_ERROR_VALUE; /* SD_INFO2, SD_INFO1のエラービット確認用変数 */ + +static u16 SD_port_en_numbers; /* サポートするポート数 */ + + + +/*ポート状態保存*/ +static SDPortContext SDPort0Context; +static SDPortContext SDPort1Context; +//SDPortContext *SDPortCurrentContext = &SDPort0Context; /*TODO*/ + + + +static u16 TransCount; /* R/W転送カウント変数 */ + +static u32 ulSDCARD_Size; /* カード全セクタ数 */ + +static volatile s16 SDCARD_ATC0_Flag; /* 全ATC完了フラグ */ +static volatile s16 SDCARD_FPGA_Flag; /* FPGA処理完了フラグ */ +static volatile s16 SDCARD_EndFlag; /* 転送処理完了フラグ */ + +extern volatile SDMC_ERR_CODE SDCARD_ErrStatus; /* エラーステータス */ +extern volatile u32 SDCARD_Status; /* カードステータス */ + +static s16 SDCARD_SDFlag; /* SDカードフラグ */ + +static volatile s16 SDCARD_OutFlag; /* カード排出発生判定フラグ */ +static SdmcResultInfo *pSDCARD_info; /* 保存用実行結果構造体ポインタ */ + +static u16 SDCARD_IO_Port; /* カード挿入/排出割り込み発生時のポート番号 */ + +void (*func_SDCARD_In)(void); /* カード挿入イベント用コールバック保存用 */ +void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */ +/* void (*func_SDCARD_CallBack)(SdmcResultInfo *info); 処理結果通知用コールバック保存用 */ + + +/*---------------------------------------------------------------------------* + Name: sdmcClearPortContext + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void sdmcClearPortContext( SDPortContext* buf_adr) +{ + MI_CpuFill8( buf_adr, 0x00, sizeof(SDPortContext)); +} + +/*---------------------------------------------------------------------------* + Name: sdmcCheckPortContext + + Description: + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcCheckPortContext( SDPortContext* buf_adr) +{ + if( (buf_adr->SD_CID[0] != 0)&&(buf_adr->port_no < 2)) { + return( SDMC_NORMAL); + }else{ + return( SDMC_ERR_PARAM); + } +} + +/*---------------------------------------------------------------------------* + Name: sdmcSavePortContext + + Description: ポート0のレジスタや変数をユーザバッファに退避する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcSavePortContext( SDPortContext* buf_adr, u16 port_no) +{ + if( buf_adr == NULL) { + return( SDMC_ERR_PARAM); + } + switch( port_no) { + case 0: + MI_CpuCopy8( &SDPort0Context, buf_adr, sizeof(SDPortContext)); + buf_adr->port_no = 0; + break; + case 1: + MI_CpuCopy8( &SDPort1Context, buf_adr, sizeof(SDPortContext)); + buf_adr->port_no = 1; + break; + default: return( SDMC_ERR_PARAM); + } + return( SDMC_NORMAL); +} + +/*---------------------------------------------------------------------------* + Name: sdmcLoadPortContext + + Description: ポート0のレジスタや変数をユーザバッファから復帰する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcLoadPortContext( SDPortContext* buf_adr, u16* port_no) +{ + if( buf_adr == NULL) { + return( SDMC_ERR_PARAM); + } + switch( buf_adr->port_no) { + case 0: + MI_CpuCopy8( buf_adr, &SDPort0Context, sizeof(SDPortContext)); + *port_no = 0; + break; + case 1: + MI_CpuCopy8( buf_adr, &SDPort1Context, sizeof(SDPortContext)); + *port_no = 1; + break; + default: return( SDMC_ERR_PARAM); + } + return( SDMC_NORMAL); +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_Backup_port0 + + Description: backup registers and variables of port0. + ポート0のレジスタや変数をバックアップする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Backup_port0(void) +{ + /* registers */ + SD_GetFPGA(SDPort0Context.SD_CLK_CTRL_VALUE,SD_CLK_CTRL); + SD_GetFPGA(SDPort0Context.SD_OPTION_VALUE, SD_OPTION); + + /* variables */ + SDPort0Context.SD_RCA = SD_RCA; + SDPort0Context.ErrStatus = SDCARD_ErrStatus; + SDPort0Context.Status = SDCARD_Status; + SDPort0Context.MMCFlag = SDCARD_MMCFlag; + SDPort0Context.SDHCFlag = SDCARD_SDHCFlag; + SDPort0Context.SDFlag = SDCARD_SDFlag; + + SDPort0Context.OutFlag = SDCARD_OutFlag; + + /*media registers*/ + MI_CpuCopy8( SD_CID, SDPort0Context.SD_CID, 16); + MI_CpuCopy8( SD_CSD, SDPort0Context.SD_CSD, 16); + MI_CpuCopy8( SD_OCR, SDPort0Context.SD_OCR, 4); + MI_CpuCopy8( SD_SCR, SDPort0Context.SD_SCR, 8); +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Backup_port1 + + Description: backup registers and variables of port1. + ポート1のレジスタや変数をバックアップする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Backup_port1(void) +{ + /* registers */ + SD_GetFPGA(SDPort1Context.SD_CLK_CTRL_VALUE,SD_CLK_CTRL); + SD_GetFPGA(SDPort1Context.SD_OPTION_VALUE, SD_OPTION); + + /* variables */ + SDPort1Context.SD_RCA = SD_RCA; + SDPort1Context.ErrStatus = SDCARD_ErrStatus; + SDPort1Context.Status = SDCARD_Status; + SDPort1Context.MMCFlag = SDCARD_MMCFlag; + SDPort1Context.SDHCFlag = SDCARD_SDHCFlag; + SDPort1Context.SDFlag = SDCARD_SDFlag; + + /*TODO:削れる*/ + SDPort1Context.OutFlag = SDCARD_OutFlag; + + /*media registers*/ + MI_CpuCopy8( SD_CID, SDPort1Context.SD_CID, 16); + MI_CpuCopy8( SD_CSD, SDPort1Context.SD_CSD, 16); + MI_CpuCopy8( SD_OCR, SDPort1Context.SD_OCR, 4); + MI_CpuCopy8( SD_SCR, SDPort1Context.SD_SCR, 8); +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcEnable + + Description: assign OS resouce for using SD memory card. + SDカードを使うための準備をする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void i_sdmcEnable( void) +{ +#if (TARGET_OS_CTR == 1) + /*SD interrupt setting*/ +// osInitIntrFlag(); +// osClearInterruptPendingID( OS_INTR_ID_SD); +// *(vu32*)CTR_INT_IF = CTR_IE_SD_MASK; + osSetInterruptHandler( OS_INTR_ID_SD, SDCARD_irq_Handler); + osEnableInterruptID( OS_INTR_ID_SD); +// *(vu32*)CTR_INT_SE = CTR_IE_SD_MASK; //割り込み(IRQ)発生許可 +// *(vu32*)CTR_INT_IE = CTR_IE_SD_MASK; +// osEnableInterrupts(); +// *(vu16*)0x04000208 = 1; +#else + /*SD割り込みのIF解除*/ +PRINTDEBUG( "%d\n", __LINE__); + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; + OS_SetIrqFunction( OS_IE_SD1, SDCARD_irq_Handler); + OS_EnableIrqMask( OS_IE_SD1); +#endif +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcDisable + + Description: under construction + 工事中 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void i_sdmcDisable( void) +{ +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_irq_Handler + + Description: SD interrupt handler + SD割り込みハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_irq_Handler( void) +{ +#if (TARGET_OS_CTR == 1) + iwup_tsk( sdmc_intr_tsk_id); +#else + PRINTDEBUG( "SD irq!\n"); + OS_SetIrqCheckFlag( OS_IE_SD1); + SDCARD_Intr_Thread( NULL); +//TODO! OS_WakeupThreadDirect( &sdmc_intr_tsk); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Dmy_Handler + + Description: dmy handler for timer interrupt. + タイマー割り込み用ダミーハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Dmy_Handler( void) +{ +} + +/*---------------------------------------------------------------------------* + Name: sdmcInit + + Description: Initialize SD interface and SD card. + 初期化 + + Arguments: dma_no : 使用するDMA番号 + func1 : カード挿入時コールバック関数 + func2 : カード排出時コールバック関数 + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcInit( SDMC_DMA_NO dma_no, void (*func1)(),void (*func2)()) +{ + SDMC_ERR_CODE api_result; + + /**/ + sdmc_dma_no = dma_no; + + if( sdmc_tsk_created == FALSE) { +#if 0 + /*---------- OS準備 ----------*/ + if( !OS_IsAlarmAvailable()) { /* アラームチェック(OS_InitAlarm済みか?) */ + SDCARD_ErrStatus |= SDMC_ERR_END; + }else{ + OS_CreateAlarm( &sdmc_alm); //使用可能であれば初期化 + } + /*----------------------------*/ +#endif + /**/ + sdmc_tsk_created = TRUE; + } + + /**/ + func_SDCARD_In = func1; /* カード挿入イベント用関数のアドレスを設定 */ + func_SDCARD_Out = func2; /* カード排出イベント用関数のアドレスを設定 */ + api_result = sdmcGoIdle( func1, func2); +// api_result = SDMC_NORMAL; + + return api_result; +} + +/* カードが入れ換わったときなどに初期化(RTFS用)*/ +SDMC_ERR_CODE sdmcGoIdle( void (*func1)(),void (*func2)()) +{ + SDCARDMsg SdMsg; + SDMC_ERR_CODE api_result; + + func_SDCARD_In = func1; /* カード挿入イベント用関数のアドレスを設定 */ + func_SDCARD_Out = func2; /* カード排出イベント用関数のアドレスを設定 */ + + /*----- SDスレッドと通信 -----*/ + SdMsg.operation = SD_OPERATION_INIT; + api_result = SDCARD_Thread( &SdMsg); + /*----------------------------*/ + + return api_result; +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcInit + + Description: Initialize SD interface and SD card. + 初期化 + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcInit( void) +{ + i_sdmcEnable(); + + /* SD初期化 */ + SDCARD_ErrStatus = sdmcReset(); + + if(!SDCARD_ErrStatus) { + SDCARD_ErrStatus = i_sdmcMPInit(); + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: sdmcReset + + Description: reset SD card. + リセット + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReset( void) +{ + OSIntrMode irq_core_flag; + ulSDCARD_Size = 0; /* カード全セクタ数クリア */ + SDCARD_MMCFlag = FALSE; /* MMCカード判定フラグクリア */ + SDCARD_SDHCFlag = FALSE; + SDCARD_SDFlag = FALSE; /* SDカード判定フラグクリア */ + + /*** カードステータスをクリア ***/ + SDCARD_ErrStatus = SDMC_NORMAL; + SDCARD_Status = SDMC_NORMAL; + + /*** カードCSD WPビットをクリア ***/ + SDCARD_WP_FLAG0 = 0; + SDCARD_WP_FLAG1 = 0; + SDCARD_WP_PERMANENT = 0; + SDCARD_WP_TEMPORARY = 0; + + pSDCARD_info = NULL; + SDCARD_OutFlag = FALSE; /* カード排出発生判定フラグクリア */ + +#if (TARGET_OS_CTR == 1) + irq_core_flag = osDisableInterrupts(); /* 割込み禁止 */ +#else + irq_core_flag = OS_DisableInterrupts(); /* 割込み禁止 */ +#endif + *SDIF_CNT_L = 0x0402; //ラッパーレジスタ + *SDIF_CNT_L = 0x0000; //ラッパーレジスタ + *SDIF_FDS_L = 0; + *SDIF_FSC_L = 1; + SD_Init(); /* SD Card I/F 初期化処理 */ + SD_AndFPGA( SD_OPTION, SD_CD_DETECT_TIME); /* CD 検出タイムをゼロクリア */ + + SD_port_en_numbers = SDCARD_PORT_NO_MAX; /*** サポートするポート数をデフォルトに設定 ***/ + SD_port_number = 0; /*** 現在のポート番号をデフォルトに設定 ***/ + + SDCARD_Backup_port0(); /* port0 backup */ + SDCARD_Backup_port1(); /* port1 backup */ + +#if (TARGET_OS_CTR == 1) + osRestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#else + OS_RestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ +#endif + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Layer_Init + + Description: initialize sequence for SD card. + SDカード規定の初期化手順 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARD_Layer_Init(void) +{ + u32 ulCSize; + u16 read_block_len_val, mult_val; + +// u16 memory_exist, function_number; + SDCARD_Status = SDMC_NORMAL; /* カードステータスをクリア */ +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + SDCARD_MMCFlag = FALSE; /* MMCカード判定フラグクリア */ + SDCARD_SDHCFlag = FALSE; + SDCARD_SDFlag = FALSE; /* SDカード判定フラグクリア */ + SDCARD_OutFlag = FALSE; /* カード排出発生判定フラグクリア */ + ulSDCARD_Size = 0; /* カード全セクタ数クリア */ + TransCount = 0; /* 転送カウント変数クリア */ + + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_128)); /* SDクロックの周波数 261KHz(初期化時は100〜400khz) */ + SD_EnableClock(); /* SDカードのクロックをイネーブルにする */ + + /* SD I/F部ダミー80クロック(1mSec)転送待ち(タイマーで待ちを実装しても良い) */ + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RESET_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + PRINTDEBUG( " CMD0(GO_IDLE_STATE)\n"); + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウト以外のエラーをクリア */ + { +/*PRINTDEBUG( "SD_INFO1 : 0x%x\n", SD_INFO1); +PRINTDEBUG( "SD_INFO2 : 0x%x\n", SD_INFO2); +PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", SD_INFO1_MASK); +PRINTDEBUG( "SD_INFO2_MASK : 0x%x\n", SD_INFO2_MASK); +PRINTDEBUG( "SD_CLK_CTRL : 0x%x\n", SD_CLK_CTRL); +PRINTDEBUG( "SD_SIZE : 0x%x\n", SD_SIZE); + +PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", (*(vu32 *)(SD_IP_BASE + 0x20)));*/ + } + SD_Command(SD_CMD_CMD | GO_IDLE_STATE); /* CMD0発行、レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /*------- idle state -------*/ + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us + SD_SendIfCond(); /* CMD8発行、レスポンス確認 */ + if( !SDCARD_SDHCFlag) { /* SDHC以外は失敗してるはずなので */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーフラグをクリアしておく */ + } + + while(!(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT)){ /* タイムアウトになったら抜ける */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); + + SD_RCA = 0; /* RCA = 0をセット */ + if(!SDCARD_MMCFlag){ /* MMCカードフラグが 0(OFF) か? */ + if(!SD_AppCommand()){ /* CMD55 発行処理が正常か? */ + SDCARD_MMCFlag = FALSE; /* MMCカードフラグクリア */ + if(!SD_AppOpCond()){ /* ACMD41発行処理が正常か?(OCR31bit = L の時 No Response) */ + SDCARD_SDFlag = TRUE; /* SDカードフラグセット */ + break; + } + }else{ /* CMD55 が正常終了しない */ + if(SDCARD_ErrStatus == SDMC_ERR_TIMEOUT){ /* タイムアウト(==No Response)か? */ + SDCARD_MMCFlag = TRUE; /* MMCカードフラグセット */ + }else{ +// break; //コメントアウトしないとSDカードの初期化に失敗する + } + } + } + if(SDCARD_MMCFlag){ /* MMCカードフラグが 1(ON) のとき */ + SD_RCA = 1; /* RCA = 1をセット */ + if(!SD_SendOpCond()){ /* CMD1発行処理が正常か? */ + break; + } + } + } +/* + if( SDCARD_SDHCFlag) { + SD_ReadOCR(); + } +*/ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーかチェック */ + SD_ClrErr(SDMC_ERR_FPGA_TIMEOUT); /* タイムアウトエラーの設定クリア */ + SD_SetErr(SDMC_ERR_RESET); /* 初期化カードリセットコマンド時1.5秒タイムアウトエラーの設定 */ + } + SDCARD_MMCFlag = FALSE; /* MMCカードフラグクリア */ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_INITIAL_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif +PRINTDEBUG( "%d\n", __LINE__); + + SD_SendCID(); /* CMD2発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + while(1){ + /******************/ + SDCARD_TimerCheck(); + /******************/ + SD_SendRelativeAddr(); /* CMD3発行 レスポンス確認 正常終了時 RCA<-ResのRCA */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + if(SD_RCA != 0){ + break; + } + } + + /*------- standby state -------*/ + SD_SendCSD(); /* CMD9発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); + + /* 転送速度設定 */ + SD_ClockDivSet(SD_RSP5); /* SDカードの動作クロック設定 (CSD[5]) */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /* Command toggles acard between the Stand-by and Transfer states */ + SD_SelectCard(); /* CMD7発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /*------- translate state -------*/ + + SDCARD_SectorSize = SECTOR_SIZE; /* セクタサイズ デフォルト 512bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* CMD16 ブロックサイズの設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + +#if SCR + SD_SelectBitWidth(FALSE); /* CMD55->ACMD6 ビット幅の選択 1bit */ + + /* ACMD51 発行 SD configuration register (SCR) */ + if(SDCARD_SDFlag){ /* SDカードフラグ ON かチェック */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + i_sdmcSendSCR(); + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } +#if TIMEOUT + SDCARD_TimerStart(SDCARD_CLOCK_WAIT);/* タイムアウト判定用タイマスタート */ +#endif + } +#endif + SD_EnableClock(); /* SD-CLK Enable */ + + if(SDCARD_MMCFlag){ /* MMCカード ON かチェック */ + if( ((SD_CSD[7] & 0x3C)>>2) >= 4) { + MMCP_SetBusWidth( TRUE); + } +// SD_SelectBitWidth(FALSE); /* CMD55->ACMD6 ビット幅の選択 1bit */ + }else{ + SD_SelectBitWidth(TRUE); /* CMD55->ACMD6 ビット幅の選択 4bit */ + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + + if(SDCARD_SDFlag){ /* SDカードフラグ ON かチェック */ + if (SDCARD_SD_Status()) /* CMD55->ACMD13 カードステータスを取得 */ + return SDCARD_ErrStatus; + if(SD_SDSTATUS[1] & SD_MEMORY_CARD){ + SDCARD_SDFlag = FALSE; /* SDカードフラグクリア */ + } + } + + /*--------------カードサイズの算出---------------*/ + if( ((SD_CSD[7] & CSD_STRUCT_BIT_127_126) >> 6) == 0x1) { //SDHCのとき + sdmc_current_spec.csd_ver2_flag = 1; + ulCSize = (u32)((((u32)(SD_CSD[3]) & CSD_C_SIZE_BIT_69_56) << 8) + + ((SD_CSD[2] & CSD_C_SIZE_BIT_55_48) >> 8) + 1); + ulCSize = ulCSize * 1024; //もともと512KByte単位なのを512Byte単位にする + /* データ領域サイズ算出 */ + sdmc_current_spec.memory_capacity = ulCSize; + ulSDCARD_Size = ulCSize; + /* プロテクト領域サイズ算出 */ + sdmc_current_spec.protected_capacity = (((SD_SwapByte( &SD_SDSTATUS[2])) << 16) + + (SD_SwapByte( &SD_SDSTATUS[3]))) / 0x200; + /*トータルサイズ算出 */ + sdmc_current_spec.card_capacity = sdmc_current_spec.memory_capacity + + sdmc_current_spec.protected_capacity; + + }else{ //従来SDカードのとき + sdmc_current_spec.csd_ver2_flag = 0; + ulCSize = (u32)(((SD_CSD[3] & CSD_C_SIZE_BIT_71_62) >> 6) + + ((SD_CSD[4] & CSD_C_SIZE_BIT_73_72) << 10) + 1); + mult_val = ((SD_CSD[2] & CSD_C_SIZE_MULT) >> 7) + 2; //2の乗数 + ulCSize = ulCSize << mult_val; + if(SDCARD_MMCFlag){ /* MMCカードフラグON かチェック */ + read_block_len_val = ((SD_CSD[4] & CSD_READ_BL_LEN) >> 8); + ulCSize = (ulCSize << read_block_len_val); + }else{ /* SDカードフラグ(SDCARD_SDFlag)ON のはず */ + read_block_len_val = (((SD_CSD[1] & CSD_WRITE_BL_LEN_BIT_25_24) << 2) | + ((SD_CSD[0] & CSD_WRITE_BL_LEN_BIT_23_22) >> 14)); + ulCSize = (ulCSize << read_block_len_val); + } + /* データ領域サイズ算出 */ + ulCSize /= SDCARD_SectorSize; /* 全セクタ数の算出 */ + sdmc_current_spec.memory_capacity = ulCSize; + ulSDCARD_Size += ulCSize; /* 全セクタ数のセット */ + /* プロテクト領域サイズ算出 */ + sdmc_current_spec.protected_capacity = ((SD_SwapByte( &SD_SDSTATUS[2])) << 16) + + (SD_SwapByte( &SD_SDSTATUS[3])); + sdmc_current_spec.protected_capacity <<= mult_val; + sdmc_current_spec.protected_capacity <<= read_block_len_val; + sdmc_current_spec.protected_capacity /= SDCARD_SectorSize; //TODO:構造体にまとめること + /*トータルサイズ算出 */ + sdmc_current_spec.card_capacity = sdmc_current_spec.memory_capacity + + sdmc_current_spec.protected_capacity; + } + sdmc_current_spec.SS = SDCARD_SectorSize; + + PRINTDEBUG( "SD memory capacity : 0x%x\n", sdmc_current_spec.memory_capacity); + PRINTDEBUG( "SD protected capacity : 0x%x\n", sdmc_current_spec.protected_capacity); + PRINTDEBUG( "SD total capacity : 0x%x\n", sdmc_current_spec.card_capacity); + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcMPInit + + Description: initialize SD card in multi ports. + マルチポートのSDカード初期化 + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcMPInit( void) +{ + u16 load_port_no; + SDPortContext* SDNandContext; + + //予約領域のポートコンテキスト参照 + SDNandContext = (SDPortContext*)&(((OSFromBromBuf*)OSi_GetFromBromAddr())->SDNandContext); +#if 0 + OS_TPrintf( "CID[0]:0x%x\n", SDNandContext->SD_CID[0]); + OS_TPrintf( "CID[1]:0x%x\n", SDNandContext->SD_CID[1]); + OS_TPrintf( "CID[2]:0x%x\n", SDNandContext->SD_CID[2]); + OS_TPrintf( "CID[3]:0x%x\n", SDNandContext->SD_CID[3]); + OS_TPrintf( "CID[4]:0x%x\n", SDNandContext->SD_CID[4]); + OS_TPrintf( "CID[5]:0x%x\n", SDNandContext->SD_CID[5]); + OS_TPrintf( "CID[6]:0x%x\n", SDNandContext->SD_CID[6]); + OS_TPrintf( "CID[7]:0x%x\n", SDNandContext->SD_CID[7]); + OS_TPrintf( "port_no:0x%x\n", SDNandContext->port_no); +#endif + + //NANDスロットの初期化 + SD_SetFPGA( SD_PORTSEL, SDMC_PORT_NAND); /* NANDポート選択 */ + +// OS_TPrintf( "SDNandContext : 0x%x\n", SDNandContext); + //初期化済みでないときだけ初期化 + if( sdmcCheckPortContext( SDNandContext) != SDMC_NORMAL) { +// OS_TPrintf( "sdmcCheckPortContext : ERR!\n"); + SDCARD_ErrStatus = SDCARD_Layer_Init(); + + SDCARD_Backup_port1(); //TODO:ポート番号 + //ポートコンテキストの保存 + if( i_sdmcSavePortContext( SDNandContext, 1) != SDMC_NORMAL) { +// OS_TPrintf( "i_sdmcSavePortContext failed\n"); + return( SDMC_ERR_PARAM); + } + }else{ //ポートコンテキストの復帰 +// OS_TPrintf( "sdmcCheckPortContext : NORMAL\n"); + + /*SDCARD_Layer_Init()の代わり*/ + SDCARD_SectorSize = SECTOR_SIZE; /* セクタサイズ デフォルト 512bytes */ + + if( i_sdmcLoadPortContext( SDNandContext, &load_port_no) != SDMC_NORMAL) { +// OS_TPrintf( "i_sdmcLoadPortContext failed\n"); + return( SDMC_ERR_PARAM); + } + SDCARD_Restore_port1(); //TODO:load_port_no値判定 + } + + SDCARD_OutFlag = FALSE; /* 排出フラグをリセット */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + SD_DisableClock(); /* SD-CLK Disable */ + SD_EnableInfo(); /* SD Card 挿抜 割り込み許可 */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcGetStatus + + Description: get card status + カードの状態を取得する + bit15 SDカード判別ビット(検出したら1) + bit14 MMCカード判別ビット(検出したら1) + bit10 IO3 card detect(検出したら1) ※CTRではプルアップのため使えない + bit9 IO3 card inserted(挿入動作で1) ※CTRではプルアップのため使えない + bit8 IO3 card removed(脱動作で1) ※CTRではプルアップのため使えない + bit7 write protect(書き込み禁止の場合1) + bit5 card detect(検出したら1) + bit4 card inserted(挿入動作で1) + bit3 card removed(脱動作で1) + bit2 R/W access all end + bit0 Response end + + Arguments: *status : カードの状態を格納する変数へのポインタ + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +/*----------------------------------------------- +SD_INFO1レジスタ +bit[10,9,8,7] = DAT3CD, DAT3IN, DAT3OUT, WP +bit[5, 4, 3, 2] = CD, INS, REM, ALLEND +bit0 = RESEND +------------------------------------------------- +EXT_CDレジスタ +bit[2,1,0] = P1CD, P1INS, P1REM +------------------------------------------------- +EXT_CD_DAT3レジスタ +bit[2, 1, 0] = P1DCD, P1DINS, P1DREM +------------------------------------------------- +EXT_WPレジスタ +bit0 = P1WP +-----------------------------------------------*/ +SDMC_ERR_CODE sdmcGetStatus(u16 *status) +{ + u16 SD_INFO1_STATUS; + + SD_INFO1_STATUS = SD_INFO1; /* SD_INFO1レジスタ読み出し */ + *status = SD_INFO1_STATUS; /* 論理反転 */ + + /*--- ポート0のとき ---*/ + if(SD_port_number == SDCARD_PORT0) + { + *status &= SDCARD_FLAG_CLR; /* SD/MMCフラグクリア */ + } + /*--- ポート1のとき ---*/ + else if (SD_port_number == SDCARD_PORT1) + { + *status &= SDCARD_PORT1_CLR; /* port1に関係ない部分をクリア */ + SD_INFO1_STATUS = (u16)((EXT_CD & 0x0007) << 3); + SD_INFO1_STATUS |= ((EXT_CD_DAT3 & 0x0007) << 8); + SD_INFO1_STATUS |= ((EXT_WP & 0x0001) << 7); + *status |= SD_INFO1_STATUS; /* カードport1フラグ設定 */ + } + /*--- SD/MMCフラグをセット ---*/ + if( SDCARD_MMCFlag) { /* 検出したカードがMMCカードの時 */ + *status |= SDCARD_FLAG_MMC; /* カード判定部分MMCカード */ + } + if( SDCARD_SDFlag) { /* 検出したカードがSDカードの時 */ + *status |= SDCARD_FLAG_SD; /* カード判定部分SDカード */ + } + + return SDMC_NORMAL; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_GetR1Status + + Description: get the card status of R1 response. + R1レスポンスのカードステータスを取得する。 + + Arguments: None + + Returns: SDCARD_Status : R1の[39:8] + *---------------------------------------------------------------------------*/ +static u32 SDCARD_GetR1Status(void) +{ + /* SD_CheckStatusでSDCARD_Statusに値が入る */ + return SDCARD_Status; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcReadFifo + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; + SDMC_ERR_CODE api_result; //SDCARD関数の返り値 + + SDCARD_USR_TRANSFER_FUNC = NULL; //ライブラリ内部関数によるリード + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ_WITH_FIFO; + + api_result = SDCARD_Thread( &SdMsg); + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: sdmcReadStreamBegin + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReadStreamBegin( u32 offset, SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; + SDMC_ERR_CODE api_result; //SDCARD関数の返り値 + + SDCARD_STREAM_FLAG = TRUE; + + SdMsg.buf = NULL; + SdMsg.bufsize = 1; + SdMsg.offset = offset; + SdMsg.func = NULL; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ_WITH_FIFO_STREAM_BEGIN; + + api_result = SDCARD_Thread( &SdMsg); + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: sdmcReadStreamEnd + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReadStreamEnd( SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; + SDMC_ERR_CODE api_result; //SDCARD関数の返り値 + + SDCARD_STREAM_FLAG = FALSE; + + SdMsg.buf = NULL; + SdMsg.bufsize = 1; + SdMsg.func = NULL; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ_WITH_FIFO_STREAM_END; + + api_result = SDCARD_Thread( &SdMsg); + + return api_result; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcReadFifoDirect + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcReadFifoDirect(sdmcTransferFunction usr_func, + u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; + SDMC_ERR_CODE api_result; //SDCARD関数の返り値 + + SDCARD_USR_TRANSFER_FUNC = usr_func; //User関数による直接リード + + SdMsg.buf = NULL; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ_WITH_FIFO; + + api_result = SDCARD_Thread( &SdMsg); + + return api_result; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARDi_ReadFifo + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_ReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDMC_ERR_CODE result; + + /* FIFO Empty割り込み無効、FIFO Full割り込み有効 */ + *(SDIF_CNT) = (*(SDIF_CNT) & (~SDIF_CNT_FEIE)) | SDIF_CNT_FFIE; + *(SDIF_FDS) = (u16)SDCARD_SectorSize; /* FIFOのデータサイズ */ + *(SDIF_FSC) = bufsize; + *(SDIF_CNT) |= (SDIF_CNT_USEFIFO | SDIF_CNT_FCLR); /* FIFO使用フラグON */ + CC_EXT_MODE = CC_EXT_MODE_DMA; /* DMAモードON */ + + result = SDCARDi_Read( buf, bufsize, offset, func, info); + + /* FIFO無効に */ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* FIFO使用フラグOFF */ + CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */ + + return result; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARDi_ReadFifoStreamBegin + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_ReadFifoStreamBegin(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + /* FIFO Empty割り込み無効、FIFO Full割り込み有効 */ + *(SDIF_CNT) = (*(SDIF_CNT) & (~SDIF_CNT_FEIE)) | SDIF_CNT_FFIE; + *(SDIF_FDS) = (u16)SDCARD_SectorSize; /* FIFOのデータサイズ */ + *(SDIF_FSC) = bufsize; + *(SDIF_CNT) |= SDIF_CNT_USEFIFO; /* FIFO使用フラグON */ + CC_EXT_MODE = CC_EXT_MODE_DMA; /* DMAモードON */ + + SDCARDi_ReadBegin( buf, bufsize, offset, func, info); + + return SDMC_NORMAL; +} + +/*---------------------------------------------------------------------------* + Name: SDCARDi_ReadFifoStreamEnd + + Description: read from card. + ラッパーのFIFOを使用してカードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_ReadFifoStreamEnd( void) +{ + SDMC_ERR_CODE result; + + result = SDCARDi_ReadEnd( FALSE); + + /* FIFO無効に */ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* FIFO使用フラグOFF */ + CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */ + + return result; +} + + + +#if 0 +/*---------------------------------------------------------------------------* + Name: sdmcRead + + Description: read from card. + カードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcRead(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; + SDMC_ERR_CODE api_result; + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_READ; + + api_result = SDCARD_Thread( &SdMsg); + return api_result; +} +#endif + +/*---------------------------------------------------------------------------* + Name: SDCARDi_Read + + Description: read from card. + カードからの読み出し。 + + Arguments: buf : 読み出したデータを格納するためのバッファのアドレス + bufsize : 読み出しサイズ(セクタ数) + offset : 読み出し開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_Read(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ + SDMC_ERR_CODE result; + + SDCARDi_ReadBegin( buf, bufsize, offset, func, info); + result = SDCARDi_ReadEnd( TRUE); + + return result; +} + + +static SDMC_ERR_CODE SDCARDi_ReadBegin(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info) +{ +// s16 nRetryCount; /* リトライ回数カウント */ + +// for( nRetryCount=0; nRetryCountresult = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + } + }else{ /*--- 残りセクタ数が 0 でないとき ---*/ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + } +} + +/*---------------------------------------------------------------------------* + Name: SYSFPGA_irq + + Description: insert/remove/error/access end interrupt handler. + BREやBWE割り込みを除く割り込みのハンドラ。挿抜、エラー発生、 + アクセス終了の割り込み発生時にそれぞれの処理を行う。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SYSFPGA_irq(void) +{ + /*--- ポート0の挿抜割り込みチェックとコールバック起動 ---*/ + if(!SD_CheckFPGAReg( SD_INFO1_MASK, SD_INFO1_MASK_REMOVE)){ /* SD Card 抜け 割込み許可状態か? */ + if( SD_CheckFPGAReg( SD_INFO1, SD_INFO1_REMOVE)){ /* SD Card 抜け 発生か? */ + SD_AndFPGA( SD_INFO1,(~SD_INFO1_REMOVE)); /* INFO1の抜けフラグを落とす */ + SDCARD_OutFlag = TRUE; /* 排出フラグセット */ + if(func_SDCARD_Out){ /* コールバック関数のNullチェック */ + SDCARD_IO_Port = SDCARD_PORT0; /* カード抜けポート番号を設定 */ + func_SDCARD_Out(); /* カード抜けコールバック関数呼び出し */ + } + } + } + if(!SD_CheckFPGAReg( SD_INFO1_MASK, SD_INFO1_MASK_INSERT)){ /* SD Card 挿入 割込み許可状態か? */ + if( SD_CheckFPGAReg( SD_INFO1, SD_INFO1_INSERT)){ /* SD Card 挿入 発生か? */ + SD_AndFPGA( SD_INFO1, (~SD_INFO1_INSERT)); /* INFO1の挿入フラグを落とす */ + SDCARD_OutFlag = FALSE; /* 排出フラグリセット */ + if(func_SDCARD_In){ /* コールバック関数のNullチェック */ + SDCARD_IO_Port = SDCARD_PORT0; /* カード挿入ポート番号を設定 */ + func_SDCARD_In(); /* カード挿入コールバック関数呼び出し */ + } + } + } + /* (CTRはポート1のCD端子が未接続(常に挿入状態)なので、ポート1の挿抜チェックは行わない) */ + + /*--- 割り込み要求と割り込みマスクを保存 ---*/ + SD_GetFPGA( SD_INFO1_VALUE, SD_INFO1); + SD_GetFPGA( SD_INFO1_MASK_VALUE, SD_INFO1_MASK); + SD_GetFPGA( SD_INFO2_VALUE, SD_INFO2); + SD_GetFPGA( SD_INFO2_MASK_VALUE, SD_INFO2_MASK); + /*------------------------------------------*/ + + /*--- SD_INFO2のエラーフラグ作成 ---*/ + SD_INFO_ERROR_VALUE = (u16)(SD_INFO2_VALUE & (~SD_INFO2_MASK_VALUE)); + /*--- エラーステータス作成 (RESTIMEOUTとILAエラーのフラグは反映しない) ---*/ + SDCARD_ErrStatus |= SD_INFO_ERROR_VALUE & (~(SD_INFO2_ERR_RESTIMEOUT)) & + (~(SD_INFO2_ERR_ILA)) & SD_INFO2_MASK_ERRSET; + + /*--- RESTIMEOUTとILAエラーはフラグの位置をずらして反映する ---*/ + if( SD_INFO_ERROR_VALUE & SD_INFO2_ERR_ILA) { + SDCARD_ErrStatus |= SDMC_ERR_ILA; /* イリーガルアクセスエラー発生 */ + } + if( SD_INFO_ERROR_VALUE & SD_INFO2_ERR_RESTIMEOUT) { + SDCARD_ErrStatus |= SDMC_ERR_TIMEOUT; /* Response Time out エラー発生 */ + }/*------------------------------------------------------------*/ + + SD_AndFPGA( SD_INFO2,(~(SD_INFO2_ERROR_SET))); /* SD_INFO2のエラーフラグを全て落とす */ + if ( SDCARD_ErrStatus) { /* 何らかのエラーが発生しているか? */ + SD_OrFPGA( SD_INFO2_MASK, SD_INFO2_MASK_ERRSET); /* 全てのエラー割り込みを禁止 */ + } + /*--- SD_INFO2のエラーチェック終了 ---*/ + + + /*--- SD_INFO1の割り込み発生状況フラグ作成 ---*/ + SD_INFO_ERROR_VALUE = (u16)(SD_INFO1_VALUE & (~SD_INFO1_MASK_VALUE)); + + if( SD_INFO_ERROR_VALUE & SD_INFO1_MASK_ALL_END) { /* R/W access all end 割込み発生か? */ + SD_OrFPGA( SD_INFO1_MASK, SD_INFO1_MASK_ALL_END); /* INFO1の access all end 割込み禁止 */ + SDCARD_FPGA_Flag = TRUE; /* R/Wアクセス終了(IP処理完了)フラグセット */ + if( SDCARD_ATC0_Flag) { /* 転送完了処理(SDCARD_ATC0_irq)が完了しているか? */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + SD_TransEndFPGA(); /* 転送終了処理(割り込みマスクを禁止に戻す) */ + if( SDCARD_EndFlag == FALSE) { /* 転送が終了していないか? */ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + if( pSDCARD_info) { /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } /* 転送が終了済みのとき */ + return; + } /* 全ATC完了フラグ OFF の場合 */ + if( SDCARD_ErrStatus != SDMC_NORMAL) { /* エラーが発生している場合 */ + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + if( SDCARD_EndFlag == FALSE) { /* 転送が終了していないか? */ + SD_TransEndFPGA(); /* カード転送の終了処理 */ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグセット */ + /* SD_Init(); */ /* SD Cardインターフェース部をリセット&初期設定 */ + if( pSDCARD_info) { /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus; /* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + } + } /* R/W access all end 割り込み未発生 */ +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_TimerCheck + + Description: + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_TimerCheck( void) +{ + u16 now_tick, eval_tick; + + now_tick = ((u16)OS_GetTickLo()); + eval_tick = now_tick - sdmc_base_tick; //Tickのoverflowは1周まで許容 + + /**/ + PRINTDEBUG( "timeout : %d\n", sdmc_timeout_ms); + PRINTDEBUG( "base_tick:0x%x, now_tick:0x%x, eval_tick:0x%x\n", + sdmc_base_tick, now_tick, eval_tick); + PRINTDEBUG( "eval_tick to ms : %d\n", OS_TicksToMilliSecondsBROM32( eval_tick)); + + /**/ + if( OS_TicksToMilliSecondsBROM32( eval_tick) > sdmc_timeout_ms) { + SDCARD_Timer_irq( NULL); + } +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_TimerStart + + Description: start timer for measure timeout. + タイムアウト計測を開始する + + Arguments: tim : ms単位のタイムアウト時間 + (50msを超える値の場合は50ms単位になる) + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_TimerStart(u32 tim) +{ +#if 0 + OSTick tim_tick; + + tim_tick = OS_MilliSecondsToTicks( tim); //us単位からTick単位へ + + OS_CancelAlarm( &sdmc_alm); //アラーム破棄 + OS_SetAlarm( &sdmc_alm, tim_tick, SDCARD_Timer_irq, NULL); //アラームセット +#endif + sdmc_timeout_ms = tim; + sdmc_base_tick = OS_GetTickLo(); +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_TimerStop + + Description: stop timer + タイムアウト計測を停止する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void SDCARD_TimerStop(void) +{ +#if 0 + OS_DisableIrq(); + OS_CancelAlarm( &sdmc_alm); + OS_EnableIrq(); +#endif +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Timer_irq + + Description: timer interrupt handler. + タイマー割り込みハンドラ + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Timer_irq(void* arg) +{ +#if (SD_DEBUG_PRINT_ON == 1) + u16 tmp; + + PRINTDEBUG( ">>>Timer intr(Timeout)\n"); + + tmp = SD_INFO1; + PRINTDEBUG( "SD_INFO1 : 0x%x\n", tmp); + tmp = SD_INFO1_MASK; + PRINTDEBUG( "SD_INFO1_MASK : 0x%x\n", tmp); + tmp = SD_INFO2; + PRINTDEBUG( "SD_INFO2 : 0x%x\n", tmp); + tmp = SD_INFO2_MASK; + PRINTDEBUG( "SD_INFO2_MASK : 0x%x\n", tmp); + tmp = SD_ERR_STS1; + PRINTDEBUG( "SD_ERR_STS1 : 0x%x\n", tmp); + tmp = SD_ERR_STS2; + PRINTDEBUG( "SD_ERR_STS2 : 0x%x\n", tmp); + tmp = *(vu16 *)(SD_IF_BASE+0x00); + PRINTDEBUG( "SD_CNT : 0x%x\n", tmp); + tmp = SD_SECCNT; + PRINTDEBUG( "SD_SECCNT : 0x%x\n", tmp); +#endif + + SDCARD_ErrStatus |= SDMC_ERR_FPGA_TIMEOUT; /* タイムアウトエラービットの設定 */ + + if(SDCARD_EndFlag == FALSE){ /* 転送処理完了フラグの確認(クリア?)*/ + SDCARD_EndFlag = TRUE; /* 転送処理完了フラグをセット */ + /* SD_TransEndFPGA(); */ /* カード転送の終了処理 */ + /* SD_StopTransmission(); */ /* カード転送終了設定 */ + /* SD_Init(); */ /* SD Cardインターフェース部をリセット&初期設定 */ + if(pSDCARD_info){ /* Nullチェック */ + pSDCARD_info->result = SDCARD_ErrStatus;/* SdmcResultInfo に情報設定 */ + pSDCARD_info->resid = (ulSDCARD_SectorCount - ulSDCARD_RestSectorCount) * + SDCARD_SectorSize; /* SdmcResultInfo に処理セクタ数設定 */ + } + } + + /**/ + PRINTDEBUG( "--Wup sdTsk(Time)--\n"); +// OS_WakeupThreadDirect( &sdmc_tsk); +// OS_WakeupThread( &sdmc_tsk_q); +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcSendSCR + + Description: get SCR register. + SCRを取得する(DATライン経由で8バイト送られてくる)。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcSendSCR(void) +{ + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + + SD_EnableClock(); /* SD-CLK Enable */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 8; /* SCR レジスタ 転送サイズ 8bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 8byte 設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + if(SD_AppCommand()){ /* RCA設定後 CMD55発行処理が正常終了しない? */ + SD_DisableClock(); /* SD-CLK Disable */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; /* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = SD_SCR; /* データ格納バッファのアドレスを設定 */ + + /* 転送前の準備処理 */ + SDCARD_DataFlag = FALSE; + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if SCR + SD_SendSCR(); /* SCRの取得コマンド発行 */ + PRINTDEBUG( "--Slp Tsk--\n"); + +// OS_SleepThread( NULL); +// OS_SleepThread( &sdmc_tsk_q); + + PRINTDEBUG( "waked\n"); + + while(!SDCARD_EndFlag){ /* カードアクセス終了待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + + PRINTDEBUG( "IF:0x%x\n", *(vu16*)CTR_INT_IF); + PRINTDEBUG( "IE:0x%x\n", *(vu16*)CTR_INT_IE); + } + + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータスの取得コマンド発行処理 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理 */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ +#endif + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを戻す(default:512bytes)*/ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + + SD_DisableClock(); /* SD-CLK Disable */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcErrProcess + + Description: when error is occured, get Card Status to check and stop the + transfer. + エラー発生時の処理。カードステータスを取得し、データ転送中で + あればストップさせる。 + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcErrProcess(void) +{ + u16 usRSP0; + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_ERRPROC_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + + SD_SendStatus(); /* CMD13 addressed card sends its status register 発行、レスポンス待ち */ + + if(!SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + SD_GetFPGA( usRSP0, SD_RSP0); + usRSP0 = (u16)(( usRSP0 & RSP_R1_CURRENT_STATE) >> 1); /* カレントステートを取り出す */ + if((usRSP0 == CURRENT_STATE_DATA) || (usRSP0 == CURRENT_STATE_RCV)){ /* SDCARD Status が data rcv の時 */ + SD_Command(SD_CMD_CMD | STOP_TRANSMISSION); /* CMD12(StopTransmission)発行処理 */ + } + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: sdmcGetCardSize + + Description: get card size (number of sectors). + カードのセクタ数を取得する + + Arguments: None + + Returns: number of sectors in the SD card which inserted. + *---------------------------------------------------------------------------*/ +u32 sdmcGetCardSize(void) +{ + /* カード全セクタ数 (SDCARD_Layer_Init関数内で算出される) */ + return ulSDCARD_Size; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_SD_Status + + Description: get SD Status. + SDステータスを取得する(DATライン経由で64バイト送られてくる)。 + カードステータスではないことを留意。 + MultiBlock R/W と異なり、DATライン経由で転送されてくるSDカードの + レジスタは、MSBから先に送られてくることに注意。 + (Physical Layer Specification 2.00 p12-13参照) + + Arguments: None + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 SDCARD_SD_Status(void) +{ + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + u32 ulSaveRestSectorCount; /* 残りセクタサイズ保存用 */ + + SD_EnableClock(); /* SD-CLK Enable */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 64; /* SD_STATUS 転送サイズ 64bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 64byte 設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + + if(SD_AppCommand()){ /* RCA設定後 CMD55発行処理 が正常終了しない?*/ + SD_DisableClock(); /* SD-CLK Disable */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSaveRestSectorCount = ulSDCARD_RestSectorCount; /* 残りセクタサイズを保存(TODO:いらない?) */ + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; /* 残りセクタサイズ、セクタカウントを1に設定 */ + pSDCARD_BufferAddr = SD_SDSTATUS; /* データ格納バッファのアドレスを設定 */ + + /* 転送前の準備処理 */ + SDCARD_DataFlag = FALSE; + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + SD_SDStatus(); /* ACMD13 SD_STATUSの取得コマンド発行処理 */ + PRINTDEBUG( "--Slp Tsk--\n"); + +// OS_SleepThread( NULL); +// OS_SleepThread( &sdmc_tsk_q); + + PRINTDEBUG( "waked\n"); + + while(!SDCARD_EndFlag){ /* カードアクセス終了待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + } + + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスが何らかのエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータス取得コマンド発行、レスポンス(R1)待ち */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理 */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを戻す(default:512bytes)*/ + SD_SetBlockLength(SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + ulSDCARD_RestSectorCount = ulSaveRestSectorCount; /* 保存していた残りセクタサイズを戻す(TODO:いらない?)*/ + + SD_DisableClock(); /* SD-CLK Disable */ + + return SDCARD_ErrStatus; +} + +/*******************************************************************************/ +int MMCP_SetBusWidth( BOOL b4bit) +{ + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ +// u16 TestData; + u16 Resid; + + SD_EnableClock(); /* SD-CLK Enable */ + +#if 0 + TestData = 0x5A;//0xA5; + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 4; /* 転送サイズ 1バイト */ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 1byte 設定 */ +#endif + /*コマンド6発行*/ + MMCP_WriteBusWidth( b4bit); + SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */ + +#if 0 + /**/ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1; + pSDCARD_BufferAddr = &TestData; /* データ格納バッファのアドレスを設定 */ + SDCARD_DataFlag = FALSE; + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + + /* IPのSD_SECCNTレジスタ有効化、転送セクタ数設定(自動CMD12発行のため) */ +// SD_EnableSeccnt( ulSDCARD_RestSectorCount); + + /*バステスト*/ + MMCP_BusTest( FALSE); + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + + /**/ + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1;/* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = &Resid; /* データ格納バッファのアドレスを設定 */ + SDCARD_DataFlag = FALSE; + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + + /**/ + MMCP_BusTest( TRUE); + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if( SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + /*バステスト合格ならバス幅を4bitに拡張*/ +// if( TestData == (~(Resid))) { + if( Resid == 0xA5) { + SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */ + }else{ + SD_OrFPGA(SD_OPTION,(SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(1bit幅) */ + } + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを設定(デフォルト 512bytesに戻す)*/ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ +#endif + return( 0); +} +/*******************************************************************************/ + + +/*---------------------------------------------------------------------------* + Name: i_sdmcCheckWP + + Description: check the write protect bit in the SD_INFO1 register. + SD_INFO1レジスタのライトプロテクトビットを調べる + (0:ライトプロテクトされている、1:ライトプロテクトされていない)。 + CTRではポート1は常に1。 + + Arguments: None + + Returns: number of sectors in the SD card which inserted. + *---------------------------------------------------------------------------*/ +static u16 i_sdmcCheckWP(void) +{ + if (SD_port_number == SDCARD_PORT0) /* ポート0のとき */ + { + if(!(SD_CheckFPGAReg(SD_INFO1,SD_INFO1_WRITEPROTECT))) { //WPフラグが立っていないか? + SDCARD_ErrStatus |= SDMC_ERR_WP; //エラーフラグのWPエラービットを立てる + }else{ //WPフラグが立っていたとき + SDCARD_ErrStatus &= ~SDMC_ERR_WP; //エラーフラグのWPエラービットを落とす + } + return SDCARD_ErrStatus; + } + else if (SD_port_number == SDCARD_PORT1) /* ポート1のとき */ + { /*TWLのポート1はライトプロテクトビットが常に0(プロテクト状態)なので反転して評価*/ + if((SD_CheckFPGAReg(EXT_WP,EXT_WP_PORT1))) { //WPフラグが立っていないか? + SDCARD_ErrStatus |= SDMC_ERR_WP; //エラーフラグのWPエラービットを立てる + }else{ //WPフラグが立っていたとき + SDCARD_ErrStatus &= ~SDMC_ERR_WP; //エラーフラグのWPエラービットを落とす + } + return SDCARD_ErrStatus; + } + return SDMC_ERR_END; //ここには来ない +} + +/*---------------------------------------------------------------------------* + Name: sdmcWriteFifo + + Description: write to card. + ラッパーのFIFOを使用してカードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcWriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; + + SDMC_ERR_CODE api_result; + + SDCARD_USR_TRANSFER_FUNC = NULL; //ライブラリ内部関数によるリード + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_WRITE_WITH_FIFO; + + api_result = SDCARD_Thread( &SdMsg); + + return api_result; +} + +/*---------------------------------------------------------------------------* + Name: sdmcWriteFifoDirect + + Description: write to card. + ラッパーのFIFOを使用してカードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcWriteFifoDirect(sdmcTransferFunction usr_func, + u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; + SDMC_ERR_CODE api_result; + + SDCARD_USR_TRANSFER_FUNC = usr_func; //User関数による直接リード + + SdMsg.buf = NULL; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_WRITE_WITH_FIFO; + + api_result = SDCARD_Thread( &SdMsg); + + return api_result; +} + + +/*---------------------------------------------------------------------------* + Name: SDCARDi_WriteFifo + + Description: write to card. + ラッパーのFIFOを使用してカードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_WriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDMC_ERR_CODE result; + + /* FIFO割り込み禁止 */ + *(SDIF_CNT) = (*(SDIF_CNT) & (~(SDIF_CNT_FFIE | SDIF_CNT_FEIE))); + *(SDIF_FDS) = (u16)SDCARD_SectorSize; /* FIFOのデータサイズ */ + *(SDIF_FSC) = bufsize; + *(SDIF_CNT) |= SDIF_CNT_USEFIFO; /* FIFO使用フラグON */ + CC_EXT_MODE = CC_EXT_MODE_DMA; /* DMAモードON */ + + result = SDCARDi_Write( buf, bufsize, offset, func, info); + + /* FIFO無効に */ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* FIFO使用フラグOFF */ + CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */ + + return result; +} +#if 0 +/*---------------------------------------------------------------------------* + Name: sdmcWrite + + Description: write to card. + カードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcWrite(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + SDCARDMsg SdMsg; + SDMC_ERR_CODE api_result; + + SdMsg.buf = buf; + SdMsg.bufsize = bufsize; + SdMsg.offset = offset; + SdMsg.func = func; + SdMsg.info = info; + SdMsg.operation = SD_OPERATION_WRITE; + + api_result = SDCARD_Thread( &SdMsg); + + return api_result; +} +#endif + +/*---------------------------------------------------------------------------* + Name: SDCARDi_Write + + Description: write to card. + カードへの書き込み。 + + Arguments: buf : 書き込みデータが格納されているバッファのアドレス + bufsize : 書き込むサイズ(セクタ数) + offset : 書き込み開始オフセット(セクタ番号) + info : 実行結果を格納するための構造体へのアドレス + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARDi_Write(void* buf,u32 bufsize,u32 offset,void(*func)(),SdmcResultInfo *info) +{ + s16 nRetryCount; + u32 ulResid; + SDMC_ERR_CODE SaveErrStatus; /* エラーステータス保存用 */ + u32 SaveStatus; /* カードステータス保存用 */ + + if( func != NULL){ /* コールバック関数のNullチェック */ + return SDMC_ERR_PARAM; /* コマンドパラメータエラー */ + } + +#if WP_ena + if( i_sdmcCheckWP()) { + return SDMC_ERR_WP; /*** ライトプロテクトのチェック ***/ + } +#endif + for(nRetryCount = 0;nRetryCount < SDCARD_RETRY_COUNT;nRetryCount++){ + + SD_EnableClock(); /* SD-CLK Enable */ + +/* func_SDCARD_CallBack = func; */ + pSDCARD_info = info; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = bufsize; + pSDCARD_BufferAddr = buf; /* データ格納バッファのアドレスを設定 */ + + SDCARD_DataFlag = TRUE; + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + + /* IPのSD_SECCNTレジスタ有効化、転送セクタ数設定(自動CMD12発行のため) */ + SD_EnableSeccnt( ulSDCARD_RestSectorCount); + + /*--- ライトコマンド発行 ---*/ + if( SDCARD_SDHCFlag) { + SD_MultiWriteBlock( offset); /* ライトコマンド発行(引数:オフセット) */ + }else{ + SD_MultiWriteBlock( offset * SDCARD_SectorSize); /* ライトコマンド発行(引数:オフセット*セクタサイズ) */ + } + /*--------------------------*/ + + /**/ + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + + /* エラーが発生していないか、タイムアウト以外のエラーの場合 */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + if(!(SDCARD_ErrStatus & SDMC_ERR_R1_STATUS)){ /* コマンドレスポンス(R1)のカードステータスがエラーでないか確認 */ + SD_SendStatus(); /* カードステータスの取得コマンド発行処理 */ + SD_CheckStatus(FALSE); /* コマンドレスポンス(R1)の Card Status チェック */ + } + } + SaveStatus = SDCARD_Status; /* カードステータスの保存 */ + SaveErrStatus = SDCARD_ErrStatus; /* エラーステータスの保存 */ + if( SDCARD_ErrStatus) { /* エラーステータスの確認(エラー有り?)*/ + i_sdmcErrProcess(); /* エラー時の処理(status取得、強制停止) */ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; /* エラー終了 */ + } +#if RESID + if( SDCARD_SDFlag) { /* SDカード(MMCでない)の場合 */ + if( SDCARD_UseFifoFlag) { /*--- FIFOを使用しているときは ---*/ + *(SDIF_CNT) &= (~SDIF_CNT_USEFIFO); /* 一時的にFIFO未使用モードにする */ + CC_EXT_MODE = CC_EXT_MODE_PIO; + i_sdmcGetResid(&ulResid); /* 書き込み完了セクタ数の取得 */ + *(SDIF_CNT) |= SDIF_CNT_USEFIFO; /* FIFO使用モードに戻す */ + CC_EXT_MODE = CC_EXT_MODE_DMA; + }else{ /*--- FIFOを使用していないとき ---*/ + i_sdmcGetResid(&ulResid); /* 書き込み完了セクタ数の取得 */ + } + if(info){ + info->resid = ulResid * SDCARD_SectorSize;/*** pSDCARD_info->resid をinfo->resid に修正 柏 2000.08.31. ***/ + } + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか確認 */ + return SDCARD_ErrStatus; + } + } +#endif + SDCARD_Status = SaveStatus; /* カードステータスの復帰 */ + SDCARD_ErrStatus = SaveErrStatus; /* エラーステータスの復帰 */ +#if RESID + if( SDCARD_SDFlag) { /* SDカード(MMCでない)の場合 */ + if( bufsize != ulResid){ /* ライト済みセクタ数が正しくないか? */ + SD_SetErr( SDMC_ERR_NUM_WR_SECTORS); /* エラーフラグセット */ + } + } +#endif + if( SDCARD_ErrStatus == SDMC_NORMAL) { /* エラーステータスの確認(エラー無し?)*/ + break; + } + } + + SD_DisableClock(); /* クロック供給停止 */ + + return SDCARD_ErrStatus; +} + + +/*---------------------------------------------------------------------------* + Name: i_sdmcGetResid + + Description: get the numbers of the well written(without errors) blocks. + 書き込みが完了したセクタの数を取得する。 + + + Arguments: pResid : 書き込み完了セクタ数を返す変数へのポインタ + + Returns: 0 : success + > 0 : error + *---------------------------------------------------------------------------*/ +static u16 i_sdmcGetResid(u32 *pResid) +{ + u16 Resid[2]; + u32 ulSave_SectorSize; /* セクタサイズ保存用 */ + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + + /* ブロックサイズの設定 */ + ulSave_SectorSize = SDCARD_SectorSize; /* セクタサイズの保存 */ + SDCARD_SectorSize = 4; /* 転送サイズ 4バイト */ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 4byte 設定 */ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ +#endif + + if( SD_AppCommand()) { /* RCA設定後 CMD55発行処理 */ + return SDCARD_ErrStatus; /* エラー発生(CMD55が正常終了しない)なら戻る */ + } + +/* func_SDCARD_CallBack = NULL; */ + pSDCARD_info = NULL; + ulSDCARD_RestSectorCount = ulSDCARD_SectorCount = 1;/* 残りセクタサイズ、セクタカウントに1を設定 */ + pSDCARD_BufferAddr = Resid; /* データ格納バッファのアドレスを設定 */ + + SDCARD_DataFlag = FALSE; + SDCARD_ATC0_Flag = FALSE; /* 全ATC完了フラグクリア */ + SDCARD_FPGA_Flag = FALSE; /* FPGA処理完了フラグクリア */ + SDCARD_EndFlag = FALSE; /* 転送処理完了フラグクリア */ + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスのクリア */ + + /*--- ACMD22 ライト済みセクタ数取得コマンド発行 ---*/ + SD_SendNumWRSectors(); + /*-------------------------------------------------*/ + PRINTDEBUG( "--Slp Tsk--\n"); + PRINTDEBUG( "waked\n"); + + while( !SDCARD_EndFlag) { /* カードアクセス終了待ち */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + if( SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーか? */ + return SDCARD_ErrStatus; /* エラー終了 */ + } + } + /* エラーが発生していないか、タイムアウト以外のエラーの場合 */ + if( SDCARD_ErrStatus) { /* (タイムアウト以外に)エラー発生か? */ + i_sdmcErrProcess(); /* エラー時の処理 */ + *pResid = 0L; /* ライト済みセクタ数に 0 を設定 */ + }else{ /* エラーが発生していない場合 */ + /* SDカードのレジスタはMSBから送られてくるため並べ替えを行う */ + Resid[1] = SD_SwapByte(&Resid[1]); /* 上位 1byte と下位 1byte を入れ替える */ + (((LELONG *)pResid)->dt2word.low) = Resid[1]; /* Resid[1]の設定 */ + Resid[0] = SD_SwapByte(&Resid[0]); /* 上位 1byte と下位 1byte を入れ替える */ + (((LELONG *)pResid)->dt2word.high) = Resid[0]; /* Resid[0]の設定 */ + } + + SDCARD_SectorSize = ulSave_SectorSize; /* 保存していたセクタサイズを設定(デフォルト 512bytesに戻す)*/ + SD_SetBlockLength( SDCARD_SectorSize); /* SDカードデータ転送サイズ 512bytes 設定 */ + /* SetBlockLengthでエラーが出たらどうする? */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Restore_port0 + + Description: restore registers and variables of port0. + ポート0のレジスタや変数を復帰する。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Restore_port0(void) +{ + /* registers */ + SD_SetFPGA( SD_CLK_CTRL, SDPort0Context.SD_CLK_CTRL_VALUE); + SD_SetFPGA( SD_OPTION, SDPort0Context.SD_OPTION_VALUE); + + /* variables */ + SD_RCA = SDPort0Context.SD_RCA; + SDCARD_ErrStatus = SDPort0Context.ErrStatus; + SDCARD_Status = SDPort0Context.Status; + SDCARD_MMCFlag = SDPort0Context.MMCFlag; + SDCARD_SDHCFlag = SDPort0Context.SDHCFlag; + SDCARD_SDFlag = SDPort0Context.SDFlag; + + SDCARD_OutFlag = SDPort0Context.OutFlag; + pSDCARD_info = NULL; + + /*media registers*/ + MI_CpuCopy8( SDPort0Context.SD_CID, SD_CID, 16); + MI_CpuCopy8( SDPort0Context.SD_CSD, SD_CSD, 16); + MI_CpuCopy8( SDPort0Context.SD_OCR, SD_OCR, 4); + MI_CpuCopy8( SDPort0Context.SD_SCR, SD_SCR, 8); + + /*recalc*/ + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Restore_port1 + + Description: restore registers and variables of port0. + ポート1のレジスタや変数を復帰する。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Restore_port1(void) +{ + /* registers */ + SD_SetFPGA( SD_CLK_CTRL, SDPort1Context.SD_CLK_CTRL_VALUE); + SD_SetFPGA( SD_OPTION, SDPort1Context.SD_OPTION_VALUE); + + /* variables */ + SD_RCA = SDPort1Context.SD_RCA; + SDCARD_ErrStatus = SDPort1Context.ErrStatus; + SDCARD_Status = SDPort1Context.Status; + SDCARD_MMCFlag = SDPort1Context.MMCFlag; + SDCARD_SDHCFlag = SDPort1Context.SDHCFlag; + SDCARD_SDFlag = SDPort1Context.SDFlag; + + SDCARD_OutFlag = SDPort1Context.OutFlag; + pSDCARD_info = NULL; + + /*media registers*/ + MI_CpuCopy8( SDPort1Context.SD_CID, SD_CID, 16); + MI_CpuCopy8( SDPort1Context.SD_CSD, SD_CSD, 16); + MI_CpuCopy8( SDPort1Context.SD_OCR, SD_OCR, 4); + MI_CpuCopy8( SDPort1Context.SD_SCR, SD_SCR, 8); + + /*recalc*/ + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); +} + + +/*---------------------------------------------------------------------------* + Name: sdmcSelectedNo + + Description: get selected port number. + 選択されているポート番号を取得する + + Arguments: None + + Returns: [15:8]port numbers which supported(サポートされているポート数) + [7:0]port number which selected now(選択されているポート番号) + *---------------------------------------------------------------------------*/ +u16 sdmcSelectedNo(void) +{ + u16 i_sdmcSelect_Value; + + SD_GetFPGA(i_sdmcSelect_Value,SD_PORTSEL); /* SD_PORTSELレジスタ値を取得 */ + + return i_sdmcSelect_Value; +} + +/*---------------------------------------------------------------------------* + Name: sdmcSelect + + Description: select port. + ポートを選択する + + Arguments: select : [15:8]port numbers which supported(サポートされているポート数) + [7:0]port number which selected now(選択するポート番号) + Returns: 0 : success + >0 : error + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcSelect(u16 select) +{ + union + { + u16 Val; + struct + { + u8 L; /* 指定したいポート */ + u8 H; /* サポートされているポート */ + } PSel; + } SDCARD_PSel; + + //TODO : transferモードからstand-byモードにする? +/* if( !SDCARD_EndFlag) { // 転送が残っている場合はエラー + return SDMC_ERR_END; + } +*/ + SDCARD_PSel.Val = select; + if ((SDCARD_PSel.PSel.H > SDCARD_PORT_NO_MAX) + | (SDCARD_PSel.PSel.H < SDCARD_PORT_NO_MIN) + | (SDCARD_PSel.PSel.L > SDCARD_PORT_SELECT_NO)) + { + return SDMC_ERR_PARAM; /* コマンドパラメータエラー */ + }else{ + SD_port_en_numbers = SDCARD_PSel.PSel.H; /* 新しくサポートするポート数を保存 */ + SD_port_number = SDCARD_PSel.PSel.L; /* 新しく選択するポート番号を保存 */ + + SD_GetFPGA(SDCARD_PSel.Val,SD_PORTSEL); /* 現在のレジスタを取得 */ + + if (SDCARD_PSel.PSel.L == 0) /* 現在選択されているポートが 0 ? */ + { + SDCARD_Backup_port0(); + }else{ + SDCARD_Backup_port1(); + } + + SDCARD_PSel.Val= select; + + if (SDCARD_PSel.PSel.L == 0) /* 新しく選択されたポートが 0 ? */ + { + SDCARD_Restore_port0(); + }else{ + SDCARD_Restore_port1(); + } + + SD_SetFPGA(SD_PORTSEL,select); /* レジスタへセット */ + return SDMC_NORMAL; /* 0 リターン */ + } +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_Thread + + Description: SDメモリカードメインタスク + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARD_Thread( SDCARDMsg* SdMsg) +{ + SDMC_ERR_CODE api_result; + + while( TRUE) { + /* メッセージ待ち */ + PRINTDEBUG( "rcv mes sdThread\n"); + PRINTDEBUG( "sd task : receive command : %d\n", SdMsg->operation); + + switch( SdMsg->operation) { + case SD_OPERATION_INIT: + api_result = i_sdmcInit(); + break; +#if 0 + case SD_OPERATION_READ: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_Read( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; +#endif + case SD_OPERATION_READ_WITH_FIFO: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_ReadFifo( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + /*--stream--*/ + case SD_OPERATION_READ_WITH_FIFO_STREAM_BEGIN: + api_result = SDCARDi_ReadFifoStreamBegin( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + case SD_OPERATION_READ_WITH_FIFO_STREAM_END: + api_result = SDCARDi_ReadFifoStreamEnd(); + break; + /*----------*/ +#if 0 + case SD_OPERATION_WRITE: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_Write( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; +#endif + case SD_OPERATION_WRITE_WITH_FIFO: + PRINTDEBUG( "from:0x%x, sectors:0x%x\n", SdMsg->offset, SdMsg->bufsize); + api_result = SDCARDi_WriteFifo( SdMsg->buf, SdMsg->bufsize, + SdMsg->offset, SdMsg->func, + SdMsg->info); + break; + default: + PRINTDEBUG( "sdmc-thread error : undefined command.\n"); + api_result = SDMC_ERR_COMMAND; + break; + } + + PRINTDEBUG( "sd task : operation ends(result : 0x%x), send message begin\n", api_result); + + /*メッセージ返送*/ + return( api_result); + } +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Intr_Thread + + Description: SDメモリカード割り込み処理タスク + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Intr_Thread( void* arg) +{ + u16 sd_info1;//, sd_info2; + OSIntrMode enabled; + +// while( 1) { +// PRINTDEBUG( "next_tsk:0x%x\n", OS_SelectThread()); + PRINTDEBUG( "Slp sdIntr\n"); + + PRINTDEBUG( "sdIntr waked\n"); + /*SD割り込みのIF解除*/ + *(vu16*)CTR_INT_IF = CTR_IE_SD_MASK; + + /*--- FIFOを使うとき ---*/ + if( SDCARD_UseFifoFlag) { + sd_info1 = SD_INFO1; + if( ((*SDIF_CNT & SDIF_CNT_FULL)&&(*SDIF_CNT & SDIF_CNT_FFIE)) || + ((!(*SDIF_CNT & SDIF_CNT_NEMP))&&(*SDIF_CNT & SDIF_CNT_FEIE))) { + + PRINTDEBUG( ">>>SD Intr(FIFO)\n");// Full or Empty)\n"); + + OS_DisableIrqMask( OS_IE_SD1); + + SDCARD_FPGA_irq(); /*カードからのリードライト要求割り込み*/ + OS_EnableIrqMask( OS_IE_SD1); + + /* FIFO割り込みとALLEND割り込みがほぼ同時の場合に対応 */ + if( SD_CheckFPGAReg( sd_info1, SD_INFO1_ALL_END)) { + OS_DisableIrqMask( OS_IE_SD1); + + SYSFPGA_irq(); + OS_EnableIrqMask( OS_IE_SD1); + } + }else{ + if( SD_CheckFPGAReg( SD_INFO2, (SD_INFO2_MASK_BRE | SD_INFO2_MASK_BWE))) { + PRINTDEBUG( ">>>SD Intr(R/W Req)\n"); + //ここで自動的にラッパーのFIFO<->SD_BUF0間で通信が行われる + // if((!(*SDIF_CNT & SDIF_CNT_NEMP))&&(*SDIF_CNT & SDIF_CNT_FEIE)) { + OS_DisableIrqMask( OS_IE_SD1); + + PRINTDEBUG( "begin\n"); + SDCARD_FPGA_irq(); + PRINTDEBUG( "end\n"); + OS_EnableIrqMask( OS_IE_SD1); + }else{ + PRINTDEBUG( ">>>SD Intr(End or Err)\n"); + OS_DisableIrqMask( OS_IE_SD1); + + SYSFPGA_irq(); /*完了またはエラー割り込み*/ + OS_EnableIrqMask( OS_IE_SD1); + /**/ + } + } + /*--- FIFOを使わないとき ---*/ + }else{ + if( SD_CheckFPGAReg( SD_INFO2, (SD_INFO2_MASK_BRE | SD_INFO2_MASK_BWE))) { + PRINTDEBUG( ">>>SD Intr(R/W Req)\n"); + OS_DisableIrqMask( OS_IE_SD1); + + PRINTDEBUG( "begin\n"); + SDCARD_FPGA_irq(); /*カードからのリードライト要求割り込み*/ + PRINTDEBUG( "end\n"); + OS_EnableIrqMask( OS_IE_SD1); + }else{ + PRINTDEBUG( ">>>SD Intr(End or Err)\n"); + OS_DisableIrqMask( OS_IE_SD1); + SYSFPGA_irq(); /*完了またはエラー割り込み*/ + OS_EnableIrqMask( OS_IE_SD1); + /**/ + } + } +// } +} diff --git a/build/libraries/fatfs/ARM7/rom_sdmc/sdmc.h b/build/libraries/fatfs/ARM7/rom_sdmc/sdmc.h new file mode 100644 index 00000000..9b97f080 --- /dev/null +++ b/build/libraries/fatfs/ARM7/rom_sdmc/sdmc.h @@ -0,0 +1,77 @@ + +#ifndef __SDMC_H__ +#define __SDMC_H__ + +//#include +//#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/********************************************* + RTFS用ドライバインタフェース +*********************************************/ +#if 0 +BOOL sdmcRtfsIo( int driveno, dword block, void* buffer, word count, BOOLEAN reading); +int sdmcRtfsCtrl( int driveno, int opcode, void* pargs); +BOOL sdmcRtfsAttach( int driveno); +#endif + +BOOL sdmcCheckMedia( void); + + +/********************************************* + データ転送関数の登録関連 +*********************************************/ +typedef void (*sdmcTransferFunction)( void* sd_adr, u32 size, BOOL read_flag); + +//void sdmcSetTransferFunction( sdmcTransferFunction usr_func); + + +/********************************************* + 基本API +*********************************************/ +void sdmcClearPortContext( SDPortContext* buf_adr); +SDMC_ERR_CODE sdmcCheckPortContext( SDPortContext* buf_adr); + + +SDMC_ERR_CODE sdmcInit( SDMC_DMA_NO dma_no, void (*func1)(),void (*func2)());/* カードドライバ初期化 */ +SDMC_ERR_CODE sdmcReset( void); /* カードリセット */ + +SDMC_ERR_CODE sdmcGetStatus(u16 *status); /* カードドライバの現在の状態を取得する */ +u32 sdmcGetCardSize(void); /* カード全サイズの取得 */ + +/*SD I/FのFIFOを使ってリードする(高速)*/ +SDMC_ERR_CODE sdmcReadFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +SDMC_ERR_CODE sdmcReadFifoDirect( sdmcTransferFunction usr_func, + u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); + +SDMC_ERR_CODE sdmcReadStreamBegin( u32 offset, SdmcResultInfo *info); +SDMC_ERR_CODE sdmcReadStreamEnd( SdmcResultInfo *info); + + +/*リードする*/ +//SDMC_ERR_CODE sdmcRead(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); + +/*SD I/FのFIFOを使ってライトする(高速)*/ +SDMC_ERR_CODE sdmcWriteFifo(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +SDMC_ERR_CODE sdmcWriteFifoDirect(sdmcTransferFunction usr_func, + u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); +/*ライトする*/ +//SDMC_ERR_CODE sdmcWrite(void* buf,u32 bufsize,u32 offset,void(*func)(void),SdmcResultInfo *info); + +/*ポート選択*/ +u16 sdmcSelectedNo(void); +SDMC_ERR_CODE sdmcSelect(u16 select); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /*__SDMC_H__*/ diff --git a/build/libraries/fatfs/ARM7/rom_sdmc/sdmc_config.h b/build/libraries/fatfs/ARM7/rom_sdmc/sdmc_config.h new file mode 100644 index 00000000..7c645077 --- /dev/null +++ b/build/libraries/fatfs/ARM7/rom_sdmc/sdmc_config.h @@ -0,0 +1,87 @@ +/* +** Copyright (c) 2000-2001 Matsushita Electric Industrial Co., Ltd. +** All Rights Reserved. +*/ + +/* +** $System IP1.1 without C2 サンプルソフト +** $Subsystem カードドライバ +** $Filename CARDDRV.H +** $Version 1.0 版 +** $Date 01/02/16 +** $Log 01/02/16 rev1.0作成 +** 松下電器産業(株)半導体開発本部 +*/ + + +#ifndef __SDMC_CONFIG_H__ +#define __SDMC_CONFIG_H__ + + +#include + +#ifdef USE_OS +#include /* IP 対応レジスタ定義 */ +#endif + + + +/********************************************* + ターゲットOS +*********************************************/ +#define TARGET_OS_CTR (0) +#define TARGET_OS_NITRO (TARGET_OS_CTR ^ 1) + + +/********************************************* + SDドライバ コンフィグレーション +*********************************************/ +#define SD_DEBUG_PRINT_ON 0 /* デバッグ表示 */ + +#define WP_ena 1 /* ライトプロテクトのチェック有効 */ +#define TIMEOUT 1 /* FPGA Timeout none = FALSE */ +#define SCR 1 /* Send SCR Command = TRUE */ +#define RESID 1 /* Write Error Resid enable = TRUE */ +#define ATC_ON 0 /* ATC転送 使用/未使用 */ + +#define SecEnable 1 /* SD_SECCNTレジスタ Enable */ +#define SecDisenable 0 /* SD_SECCNTレジスタ Disable */ +//#define STANDBYMODE 0x04 /*** 5772 standby control bit ***/ + +#define SDCARD_TIMER_ID (OS_TIMER_3) + + +/********************************************* + タイムアウト設定値(ms単位) +*********************************************/ +#define SDCARD_RW_TIMEOUT (2000) +#define SDCARD_STDBY_TIMEOUT (50) +#define SDCARD_CLOCK_WAIT (500) +#define SDCARD_SDCLK_WAIT (10) +#define SDCARD_INITIAL_TIMEOUT (800) +#define SDCARD_RESET_TIMEOUT (1500) +#define SDCARD_ERASE_TIMEOUT (1) +#define SDCARD_ERRPROC_TIMEOUT (2000) + + +/********************************************* + リトライ回数(Multiple Block R/W のとき) +*********************************************/ +#define SDCARD_RETRY_COUNT (3) + +/********************************************* + その他 +*********************************************/ +#define SECTOR_SIZE (512) /* 1セクタのバイト数 */ +#define SECTOR_MAX (255) /* SYSFPGA アクセス最大セクタ数 */ + +/*--- 上位レイヤに返すステータス値(SDCARD_Getstatus参照)用 ---*/ +#define SDCARD_FLAG_CLR (0x3FFF) /* カード判定部分クリア用 */ +#define SDCARD_FLAG_SD (0x8000) /* カード判定部分SDカード */ +#define SDCARD_FLAG_MMC (0x4000) /* カード判定部分MMCカード */ +#define SDCARD_PORT1_CLR (0x0007) /* カードポート1判定部分クリア用 */ + + + + +#endif /*__SDMC_CONFIG_H__*/ diff --git a/build/libraries/fatfs/ARM7/rom_sdmc/sdmc_nandinit.c b/build/libraries/fatfs/ARM7/rom_sdmc/sdmc_nandinit.c new file mode 100644 index 00000000..8e88c79d --- /dev/null +++ b/build/libraries/fatfs/ARM7/rom_sdmc/sdmc_nandinit.c @@ -0,0 +1,637 @@ +/* + Project: TwlBrom SD port driver + File: Carddrv.c + + 2006, Research and Development Department, Nintendo. +*/ + +#include "sdmc_config.h" +#include "sdmc.h" +#include "sdif_reg.h" +#include "sdif_ip.h" +#include +//#include +//#include "sdmc_config.h" +//#include "sdif_reg.h" /* IP 対応レジスタ定義 */ +//#include +//#include "sdif_ip.h" /* IP 対応フラグ定義 */ + +// #define PRINTDEBUG OS_TPrintf + #define PRINTDEBUG( ...) ((void)0) + + +/*********************************************************************** + 定数 +***********************************************************************/ +static BOOL sdmcGetErrStat( void); + + +/*********************************************************************** + static関数の宣言 +***********************************************************************/ +static void SDCARD_Backup_port1(void); +static void SDCARD_Restore_port1(void); + +static int MMCP_SetBusWidth( BOOL b4bit); /* ビット幅の選択(MMCplus, eMMC, moviNAND) */ + +static SDMC_ERR_CODE SDCARD_Layer_Init(void); +static SDMC_ERR_CODE i_sdmcMPInit( void); /* カードドライバ初期化(マルチポート対応) */ + +/*********************************************************************** + 外部参照変数 +***********************************************************************/ +extern void SDCARD_Timer_irq(void* arg); /* タイムアウト割り込みハンドラ */ +extern void SDCARD_TimerCheck( void); +extern void SDCARD_TimerStart(u32 tim); /* タイムアウト計測スタート */ +extern void SDCARD_TimerStop(void); /* タイムアウト計測停止 */ + + +extern u16 SD_CID[8]; /* CID値保存用 */ +extern u16 SD_CSD[8]; /* CSD値保存用 */ +extern u16 SD_OCR[2]; /* OCR値保存用 */ +extern u16 SD_SCR[4]; /* SCR値保存用 */ +extern u16 SD_RCA; /* RCA値保存用 */ + +extern s16 SDCARD_MMCFlag; /* MMCカードフラグ */ +extern s16 SDCARD_SDHCFlag; /* SDHCカードフラグ */ +extern u16 SD_port_number; /* 現在ポート番号 */ + + +/*********************************************************************** + グローバル +***********************************************************************/ +static u16 SD_SDSTATUS[32]; /* SD_STATUSレジスタ保存用 */ +static u16 SDCARD_WP_FLAG0; /* カードライトプロテクトフラグ。0=なし、1=有り */ +static u16 SDCARD_WP_FLAG1; /* カードライトプロテクトフラグ。0=なし、1=有り */ +static u16 SDCARD_WP_PERMANENT; /* カードライトプロテクト永久フラグ。0=なし、1=有り */ +static u16 SDCARD_WP_TEMPORARY; /* カードライトプロテクト一時フラグ。0=なし、1=有り */ + +static u32 SDCARD_SectorSize; /* セクタサイズ デフォルト 512bytes */ + +static u16 SD_INFO1_VALUE; /* SD_INFO1レジスタ取得用変数 */ +static u16 SD_INFO1_MASK_VALUE; /* SD_INFO1割込みマスク用変数(0で許可, 1で禁止) */ +static u16 SD_INFO2_VALUE; /* SD_INFO2レジスタ取得用変数 */ +static u16 SD_INFO2_MASK_VALUE; /* SD_INFO2割り込みマスク用変数(0で許可, 1で禁止) */ +static u16 SD_INFO_ERROR_VALUE; /* SD_INFO2, SD_INFO1のエラービット確認用変数 */ + + +/*ポート状態保存*/ +static SDPortContext SDPort0Context; +static SDPortContext SDPort1Context; +//SDPortContext *SDPortCurrentContext = &SDPort0Context; /*TODO*/ + + + +extern volatile SDMC_ERR_CODE SDCARD_ErrStatus; /* エラーステータス */ +extern volatile u32 SDCARD_Status; /* カードステータス */ + +static s16 SDCARD_SDFlag; /* SDカードフラグ */ + +static volatile s16 SDCARD_OutFlag = 0; /* カード排出発生判定フラグ */ +static SdmcResultInfo *pSDCARD_info = NULL; /* 保存用実行結果構造体ポインタ */ + + +static SDMC_ERR_CODE i_sdmcSavePortContext( SDPortContext* buf_adr, u16 port_no); +static SDMC_ERR_CODE i_sdmcLoadPortContext( SDPortContext* buf_adr, u16* port_no); + + +/*---------------------------------------------------------------------------* + Name: sdmcSavePortContext + + Description: ポート0のレジスタや変数をユーザバッファに退避する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcSavePortContext( SDPortContext* buf_adr, u16 port_no) +{ + if( buf_adr == NULL) { + return( SDMC_ERR_PARAM); + } + switch( port_no) { + case 0: + MI_CpuCopy8( &SDPort0Context, buf_adr, sizeof(SDPortContext)); + buf_adr->port_no = 0; + break; + case 1: + MI_CpuCopy8( &SDPort1Context, buf_adr, sizeof(SDPortContext)); + buf_adr->port_no = 1; + break; + default: return( SDMC_ERR_PARAM); + } + return( SDMC_NORMAL); +} + +/*---------------------------------------------------------------------------* + Name: sdmcLoadPortContext + + Description: ポート0のレジスタや変数をユーザバッファから復帰する + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcLoadPortContext( SDPortContext* buf_adr, u16* port_no) +{ + if( buf_adr == NULL) { + return( SDMC_ERR_PARAM); + } + switch( buf_adr->port_no) { + case 0: + MI_CpuCopy8( buf_adr, &SDPort0Context, sizeof(SDPortContext)); + *port_no = 0; + break; + case 1: + MI_CpuCopy8( buf_adr, &SDPort1Context, sizeof(SDPortContext)); + *port_no = 1; + break; + default: return( SDMC_ERR_PARAM); + } + return( SDMC_NORMAL); +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_Backup_port1 + + Description: backup registers and variables of port1. + ポート1のレジスタや変数をバックアップする + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Backup_port1(void) +{ + /* registers */ + SD_GetFPGA(SDPort1Context.SD_CLK_CTRL_VALUE,SD_CLK_CTRL); + SD_GetFPGA(SDPort1Context.SD_OPTION_VALUE, SD_OPTION); + + /* variables */ + SDPort1Context.SD_RCA = SD_RCA; + SDPort1Context.ErrStatus = SDCARD_ErrStatus; + SDPort1Context.Status = SDCARD_Status; + SDPort1Context.MMCFlag = SDCARD_MMCFlag; + SDPort1Context.SDHCFlag = SDCARD_SDHCFlag; + SDPort1Context.SDFlag = SDCARD_SDFlag; + + SDPort1Context.OutFlag = SDCARD_OutFlag; + + /*media registers*/ + MI_CpuCopy8( SD_CID, SDPort1Context.SD_CID, 16); + MI_CpuCopy8( SD_CSD, SDPort1Context.SD_CSD, 16); + MI_CpuCopy8( SD_OCR, SDPort1Context.SD_OCR, 4); + MI_CpuCopy8( SD_SCR, SDPort1Context.SD_SCR, 8); +} + + +/*---------------------------------------------------------------------------* + Name: SDCARD_Restore_port1 + + Description: restore registers and variables of port0. + ポート1のレジスタや変数を復帰する。 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static void SDCARD_Restore_port1(void) +{ + /* registers */ + SD_SetFPGA( SD_CLK_CTRL, SDPort1Context.SD_CLK_CTRL_VALUE); + SD_SetFPGA( SD_OPTION, SDPort1Context.SD_OPTION_VALUE); + + /* variables */ + SD_RCA = SDPort1Context.SD_RCA; + SDCARD_ErrStatus = SDPort1Context.ErrStatus; + SDCARD_Status = SDPort1Context.Status; + SDCARD_MMCFlag = SDPort1Context.MMCFlag; + SDCARD_SDHCFlag = SDPort1Context.SDHCFlag; + SDCARD_SDFlag = SDPort1Context.SDFlag; + + SDCARD_OutFlag = SDPort1Context.OutFlag; + pSDCARD_info = NULL; + + /*media registers*/ + MI_CpuCopy8( SDPort1Context.SD_CID, SD_CID, 16); + MI_CpuCopy8( SDPort1Context.SD_CSD, SD_CSD, 16); + MI_CpuCopy8( SDPort1Context.SD_OCR, SD_OCR, 4); + MI_CpuCopy8( SDPort1Context.SD_SCR, SD_SCR, 8); + + /*recalc*/ + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); +} + + +/*---------------------------------------------------------------------------* + Name: sdmcNandInit + + Description: Initialize SD interface and SD card. + 初期化 + + Arguments: dma_no : 使用するDMA番号 + func1 : カード挿入時コールバック関数 + func2 : カード排出時コールバック関数 + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +SDMC_ERR_CODE sdmcNandInit( void) +{ + /* SD初期化 */ + SDCARD_ErrStatus = sdmcReset(); + + if(!SDCARD_ErrStatus) { + SDCARD_ErrStatus = i_sdmcMPInit(); + } + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: sdmcReset + + Description: reset SD card. + リセット + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE sdmcReset( void) +{ + OSIntrMode irq_core_flag; + SDCARD_MMCFlag = FALSE; /* MMCカード判定フラグクリア */ + SDCARD_SDHCFlag = FALSE; + SDCARD_SDFlag = FALSE; /* SDカード判定フラグクリア */ + + /*** カードステータスをクリア ***/ + SDCARD_ErrStatus = SDMC_NORMAL; + SDCARD_Status = SDMC_NORMAL; + + /*** カードCSD WPビットをクリア ***/ + SDCARD_WP_FLAG0 = 0; + SDCARD_WP_FLAG1 = 0; + SDCARD_WP_PERMANENT = 0; + SDCARD_WP_TEMPORARY = 0; + + irq_core_flag = OS_DisableInterrupts(); /* 割込み禁止 */ + + *SDIF_CNT_L = 0x0402; //ラッパーレジスタ + *SDIF_CNT_L = 0x0000; //ラッパーレジスタ + *SDIF_FDS_L = 0; + *SDIF_FSC_L = 1; + SD_Init(); /* SD Card I/F 初期化処理 */ + SD_AndFPGA( SD_OPTION, SD_CD_DETECT_TIME); /* CD 検出タイムをゼロクリア */ + + SD_port_number = SDCARD_PORT1; /*** 現在のポート番号をデフォルトに設定 ***/ + +// SDCARD_Backup_port1(); /* port1 backup */ + + OS_RestoreInterrupts( irq_core_flag); /* 割り込み設定を元に戻す */ + + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: SDCARD_Layer_Init + + Description: initialize sequence for SD card. + SDカード規定の初期化手順 + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE SDCARD_Layer_Init(void) +{ + u32 ulCSize; + u16 read_block_len_val, mult_val; + +// u16 memory_exist, function_number; + SDCARD_Status = SDMC_NORMAL; /* カードステータスをクリア */ + SDCARD_MMCFlag = FALSE; /* MMCカード判定フラグクリア */ + SDCARD_SDHCFlag = FALSE; + SDCARD_SDFlag = FALSE; /* SDカード判定フラグクリア */ + + SD_SetFPGA(SD_CLK_CTRL,(SD_CLK_CTRL_128)); /* SDクロックの周波数 261KHz(初期化時は100〜400khz) */ + SD_EnableClock(); /* SDカードのクロックをイネーブルにする */ + + /* SD I/F部ダミー80クロック(1mSec)転送待ち(タイマーで待ちを実装しても良い) */ + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us + + SDCARD_ErrStatus = SDMC_NORMAL; /* エラーステータスをクリア */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_RESET_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + PRINTDEBUG( " CMD0(GO_IDLE_STATE)\n"); + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); /* タイムアウト以外のエラーをクリア */ + SD_Command(SD_CMD_CMD | GO_IDLE_STATE); /* CMD0発行、レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /*------- idle state -------*/ + SVC_WaitByLoop( 17900); //179*4サイクル=716サイクル=10024ns=10us + + while(!(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT)){ /* タイムアウトになったら抜ける */ + /******************/ + SDCARD_TimerCheck(); + /******************/ + SD_ClrErr((u16)(~SDMC_ERR_FPGA_TIMEOUT)); + + SD_RCA = 0; /* RCA = 0をセット */ + + if(!SDCARD_MMCFlag){ /* MMCカードフラグが 0(OFF) か? */ + + if( SD_AppCommand() == SDMC_NORMAL) { /* CMD55 発行処理が正常か? */ + + SDCARD_MMCFlag = FALSE; /* MMCカードフラグクリア */ + if(!SD_AppOpCond()){ /* ACMD41発行処理が正常か?(OCR31bit = L の時 No Response) */ + + SDCARD_SDFlag = TRUE; /* SDカードフラグセット */ + break; + } + }else{ /* CMD55 が正常終了しない */ + if(SDCARD_ErrStatus == SDMC_ERR_TIMEOUT){ /* タイムアウト(==No Response)か? */ + SDCARD_MMCFlag = TRUE; /* MMCカードフラグセット */ + }else{ +// break; //コメントアウトしないとSDカードの初期化に失敗する + } + } + } + if(SDCARD_MMCFlag){ /* MMCカードフラグが 1(ON) のとき */ + SD_RCA = 1; /* RCA = 1をセット */ + if(!SD_SendOpCond()){ /* CMD1発行処理が正常か? */ + break; + } + } + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?)*/ + if(SDCARD_ErrStatus & SDMC_ERR_FPGA_TIMEOUT){ /* タイムアウトエラーかチェック */ + SD_ClrErr(SDMC_ERR_FPGA_TIMEOUT); /* タイムアウトエラーの設定クリア */ + SD_SetErr(SDMC_ERR_RESET); /* 初期化カードリセットコマンド時1.5秒タイムアウトエラーの設定 */ + } + SDCARD_MMCFlag = FALSE; /* MMCカードフラグクリア */ + return SDCARD_ErrStatus; + } + +#if TIMEOUT + SDCARD_TimerStart(SDCARD_INITIAL_TIMEOUT); /* タイムアウト判定用タイマスタート */ +#endif + + SD_SendCID(); /* CMD2発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + while(1){ + /******************/ + SDCARD_TimerCheck(); + /******************/ + SD_SendRelativeAddr(); /* CMD3発行 レスポンス確認 正常終了時 RCA<-ResのRCA */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + if(SD_RCA != 0){ + break; + } + } + + /*------- standby state -------*/ + SD_SendCSD(); /* CMD9発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + SDCARD_WP_PERMANENT = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_PERMANENT_BIT)); + SDCARD_WP_TEMPORARY = (u16)(SD_CSD[0] & (u16)(SDCARD_WP_TEMPORARY_BIT)); + + /* 転送速度設定 */ + SD_ClockDivSet(SD_RSP5); /* SDカードの動作クロック設定 (CSD[5]) */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /* Command toggles acard between the Stand-by and Transfer states */ + SD_SelectCard(); /* CMD7発行 レスポンス確認 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + /*------- translate state -------*/ + + SDCARD_SectorSize = SECTOR_SIZE; /* セクタサイズ デフォルト 512bytes */ + SD_SetBlockLength(SDCARD_SectorSize); /* CMD16 ブロックサイズの設定 */ + if(SDCARD_ErrStatus){ /* エラーステータスの確認(エラー有り?) */ + return SDCARD_ErrStatus; + } + + SD_SCR[0] |= SCR_DAT_BUS_WIDTH_4BIT; //SCRの必要な部分のみ + + SD_EnableClock(); /* SD-CLK Enable */ + + if(SDCARD_MMCFlag){ /* MMCカード ON かチェック */ + if( ((SD_CSD[7] & 0x3C)>>2) >= 4) { + MMCP_SetBusWidth( TRUE); + } +// SD_SelectBitWidth(FALSE); /* CMD55->ACMD6 ビット幅の選択 1bit */ + }else{ + SD_SelectBitWidth(TRUE); /* CMD55->ACMD6 ビット幅の選択 4bit */ + } + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + return SDCARD_ErrStatus; +} + +/*---------------------------------------------------------------------------* + Name: i_sdmcMPInit + + Description: initialize SD card in multi ports. + マルチポートのSDカード初期化 + + Arguments: + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +static SDMC_ERR_CODE i_sdmcMPInit( void) +{ + u16 load_port_no; + SDPortContext* SDNandContext; + + //予約領域のポートコンテキスト参照 + SDNandContext = (SDPortContext*)&(((OSFromBromBuf*)OSi_GetFromBromAddr())->SDNandContext); + + //NANDスロットの初期化 + SD_SetFPGA( SD_PORTSEL, SDMC_PORT_NAND); /* NANDポート選択 */ + +// OS_TPrintf( "SDNandContext : 0x%x\n", SDNandContext); + //初期化済みでないときだけ初期化 + if( sdmcCheckPortContext( SDNandContext) != SDMC_NORMAL) { +// OS_TPrintf( "sdmcCheckPortContext : ERR!\n"); + SDCARD_ErrStatus = SDCARD_Layer_Init(); + + SDCARD_Backup_port1(); + //ポートコンテキストの保存 + if( i_sdmcSavePortContext( SDNandContext, 1) != SDMC_NORMAL) { +// OS_TPrintf( "i_sdmcSavePortContext failed\n"); + return( SDMC_ERR_PARAM); + } + }else{ //ポートコンテキストの復帰 +// OS_TPrintf( "sdmcCheckPortContext : NORMAL\n"); + + /*SDCARD_Layer_Init()の代わり*/ + SDCARD_SectorSize = SECTOR_SIZE; /* セクタサイズ デフォルト 512bytes */ + + if( i_sdmcLoadPortContext( SDNandContext, &load_port_no) != SDMC_NORMAL) { +// OS_TPrintf( "i_sdmcLoadPortContext failed\n"); + return( SDMC_ERR_PARAM); + } + SDCARD_Restore_port1(); //TODO:load_port_no値判定 + } + + SDCARD_OutFlag = FALSE; /* 排出フラグをリセット */ + + SDCARD_TimerStop(); /* タイムアウト判定用タイマストップ */ + SD_DisableClock(); /* SD-CLK Disable */ + SD_EnableInfo(); /* SD Card 挿抜 割り込み許可 */ + + return SDCARD_ErrStatus; +} + +#if 0 +/*---------------------------------------------------------------------------* + Name: sdmcGetStatus + + Description: get card status + カードの状態を取得する + bit15 SDカード判別ビット(検出したら1) + bit14 MMCカード判別ビット(検出したら1) + bit10 IO3 card detect(検出したら1) ※CTRではプルアップのため使えない + bit9 IO3 card inserted(挿入動作で1) ※CTRではプルアップのため使えない + bit8 IO3 card removed(脱動作で1) ※CTRではプルアップのため使えない + bit7 write protect(書き込み禁止の場合1) + bit5 card detect(検出したら1) + bit4 card inserted(挿入動作で1) + bit3 card removed(脱動作で1) + bit2 R/W access all end + bit0 Response end + + Arguments: *status : カードの状態を格納する変数へのポインタ + + Returns: 0 : success + > 0 : error code + *---------------------------------------------------------------------------*/ +/*----------------------------------------------- +SD_INFO1レジスタ +bit[10,9,8,7] = DAT3CD, DAT3IN, DAT3OUT, WP +bit[5, 4, 3, 2] = CD, INS, REM, ALLEND +bit0 = RESEND +------------------------------------------------- +EXT_CDレジスタ +bit[2,1,0] = P1CD, P1INS, P1REM +------------------------------------------------- +EXT_CD_DAT3レジスタ +bit[2, 1, 0] = P1DCD, P1DINS, P1DREM +------------------------------------------------- +EXT_WPレジスタ +bit0 = P1WP +-----------------------------------------------*/ +SDMC_ERR_CODE sdmcGetStatus(u16 *status) +{ + u16 SD_INFO1_STATUS; + + SD_INFO1_STATUS = SD_INFO1; /* SD_INFO1レジスタ読み出し */ + *status = SD_INFO1_STATUS; /* 論理反転 */ + + /*--- ポート0のとき ---*/ + if(SD_port_number == SDCARD_PORT0) + { + *status &= SDCARD_FLAG_CLR; /* SD/MMCフラグクリア */ + } + /*--- ポート1のとき ---*/ + else if (SD_port_number == SDCARD_PORT1) + { + *status &= SDCARD_PORT1_CLR; /* port1に関係ない部分をクリア */ + SD_INFO1_STATUS = (u16)((EXT_CD & 0x0007) << 3); + SD_INFO1_STATUS |= ((EXT_CD_DAT3 & 0x0007) << 8); + SD_INFO1_STATUS |= ((EXT_WP & 0x0001) << 7); + *status |= SD_INFO1_STATUS; /* カードport1フラグ設定 */ + } + /*--- SD/MMCフラグをセット ---*/ + if( SDCARD_MMCFlag) { /* 検出したカードがMMCカードの時 */ + *status |= SDCARD_FLAG_MMC; /* カード判定部分MMCカード */ + } + if( SDCARD_SDFlag) { /* 検出したカードがSDカードの時 */ + *status |= SDCARD_FLAG_SD; /* カード判定部分SDカード */ + } + + return SDMC_NORMAL; +} +#endif + + +/*******************************************************************************/ +static int MMCP_SetBusWidth( BOOL b4bit) +{ + SD_EnableClock(); /* SD-CLK Enable */ + + /*コマンド6発行*/ + MMCP_WriteBusWidth( b4bit); + SD_AndFPGA(SD_OPTION,(~SD_OPTION_WIDTH_1BIT)); /* IPにビット幅の設定(4bit幅) */ + + return( 0); +} +/*******************************************************************************/ + + + +/*---------------------------------------------------------------------------* + Name: sdmcGetErrStat + + Description: エラー取得 + + Arguments: + + Returns: TRUE : success + FALSE : error + *---------------------------------------------------------------------------*/ +static BOOL sdmcGetErrStat( void) +{ + PRINTDEBUG( "SD_INFO2:0x%x\n", SD_INFO2); + + /*--- 取得 ---*/ + SD_GetFPGA( SD_INFO2_VALUE, SD_INFO2); + /*------------------------------------------*/ + + /*--- SD_INFO2のエラーフラグ作成 ---*/ + SD_INFO_ERROR_VALUE = (u16)(SD_INFO2_VALUE & 0x807F);// + /*--- エラーステータス作成 (RESTIMEOUTとILAエラーのフラグは反映しない) ---*/ + SDCARD_ErrStatus |= SD_INFO_ERROR_VALUE & (~(SD_INFO2_ERR_RESTIMEOUT)) & + (~(SD_INFO2_ERR_ILA)) & SD_INFO2_MASK_ERRSET; + + /*--- RESTIMEOUTとILAエラーはフラグの位置をずらして反映する ---*/ + if( SD_INFO_ERROR_VALUE & SD_INFO2_ERR_ILA) { + SDCARD_ErrStatus |= SDMC_ERR_ILA; /* イリーガルアクセスエラー発生 */ + } + if( SD_INFO_ERROR_VALUE & SD_INFO2_ERR_RESTIMEOUT) { + SDCARD_ErrStatus |= SDMC_ERR_TIMEOUT; /* Response Time out エラー発生 */ + }/*------------------------------------------------------------*/ + + SD_AndFPGA( SD_INFO2,(~(SD_INFO2_ERROR_SET))); /* SD_INFO2のエラーフラグを全て落とす */ + + if( (SD_INFO_ERROR_VALUE) != 0) { + return( FALSE); + }else{ + return( TRUE); + } +} diff --git a/build/libraries/fatfs/ARM7/src/fatfs_firm.c b/build/libraries/fatfs/ARM7/src/fatfs_firm.c new file mode 100644 index 00000000..c53da981 --- /dev/null +++ b/build/libraries/fatfs/ARM7/src/fatfs_firm.c @@ -0,0 +1,421 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - libraries - fatfs + File: fatfs_firm.c + + Copyright 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. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include + +#include +#include +#include +#include +#include +#include + +extern u32 NAND_FAT_PARTITION_COUNT; + +#define DMA_PIPE 2 +#define DMA_RECV 3 + +/* + 専用DMA関数 +*/ +#define MIi_SRC_INC (MI_NDMA_SRC_INC | MI_NDMA_SRC_RELOAD_DISABLE) +#define MIi_SRC_DEC (MI_NDMA_SRC_DEC | MI_NDMA_SRC_RELOAD_DISABLE) +#define MIi_SRC_FIX (MI_NDMA_SRC_FIX | MI_NDMA_SRC_RELOAD_DISABLE) +#define MIi_SRC_FILLDATA (MI_NDMA_SRC_FILLDATA | MI_NDMA_SRC_RELOAD_DISABLE) + +#define MIi_DEST_INC (MI_NDMA_DEST_INC | MI_NDMA_DEST_RELOAD_DISABLE) +#define MIi_DEST_DEC (MI_NDMA_DEST_DEC | MI_NDMA_DEST_RELOAD_DISABLE) +#define MIi_DEST_FIX (MI_NDMA_DEST_FIX | MI_NDMA_DEST_RELOAD_DISABLE) +#define MIi_DEST_INC_RELOAD (MI_NDMA_SRC_INC | MI_NDMA_DEST_RELOAD_ENABLE) + +#define MIi_IMM (MI_NDMA_IMM_MODE_ON) + +#define MIi_CONT (MI_NDMA_CONTINUOUS_ON) +//---------------- register setting +static inline void MIi_SetSrc( u32 ndmaNo, u32 src ) +{ + MI_NDMA_REG( ndmaNo, MI_NDMA_REG_SAD_WOFFSET ) = src; +} +static inline void MIi_SetDest( u32 ndmaNo, u32 dest ) +{ + MI_NDMA_REG( ndmaNo, MI_NDMA_REG_DAD_WOFFSET ) = dest; +} +static inline void MIi_SetTotalWordCount( u32 ndmaNo, u32 size ) +{ + MI_NDMA_REG( ndmaNo, MI_NDMA_REG_TCNT_WOFFSET ) = size; +} +static inline void MIi_SetWordCount( u32 ndmaNo, u32 size ) +{ + MI_NDMA_REG( ndmaNo, MI_NDMA_REG_WCNT_WOFFSET ) = size; +} +static inline void MIi_SetInterval( u32 ndmaNo, u32 intervalTimer, u32 prescaler ) +{ +#ifdef SDK_ARM7 + //---- In case of ARM7, intervalTimer==1 is nonsense + SDK_ASSERT(intervalTimer != 1); +#endif + MI_NDMA_REG( ndmaNo, MI_NDMA_REG_BCNT_WOFFSET ) = intervalTimer | prescaler; +} +static inline void MIi_SetFillData( u32 ndmaNo, u32 data ) +{ + MI_NDMA_REG( ndmaNo, MI_NDMA_REG_FDATA_WOFFSET ) = data; +} +static inline void MIi_SetControl( u32 ndmaNo, u32 contData ) +{ + MI_NDMA_REG( ndmaNo, MI_NDMA_REG_CNT_WOFFSET ) = contData; +} +static inline void MIi_NDmaRecv(u32 ndmaNo, const void *src, void *dest, u32 size) +{ + MIi_SetSrc( ndmaNo, (u32)src ); + MIi_SetDest( ndmaNo, (u32)dest ); + MIi_SetInterval( ndmaNo, MI_NDMA_NO_INTERVAL, MI_NDMA_INTERVAL_PS_1 ); + MIi_SetTotalWordCount( ndmaNo, size/4 ); + MIi_SetWordCount( ndmaNo, size/4 ); + MIi_SetControl( ndmaNo, MI_NDMA_BWORD_16 | MI_NDMA_SRC_FIX | MIi_DEST_INC | MIi_IMM | MI_NDMA_ENABLE ); +} + +static inline void MIi_NDmaPipeSetup(u32 ndmaNo, const void *src, void *dest, u32 size) +{ + MIi_SetSrc( ndmaNo, (u32)src ); + MIi_SetDest( ndmaNo, (u32)dest ); + MIi_SetInterval( ndmaNo, MI_NDMA_NO_INTERVAL, MI_NDMA_INTERVAL_PS_1 ); + MIi_SetTotalWordCount( ndmaNo, size/4 ); + MIi_SetWordCount( ndmaNo, size/4 ); + MIi_SetControl( ndmaNo, MI_NDMA_BWORD_16 | MI_NDMA_SRC_FIX | MIi_DEST_FIX | MIi_IMM ); +} + +static inline void MIi_NDmaRestart(u32 ndmaNo) +{ + MI_WaitNDma( ndmaNo ); + MI_NDMA_REG( ndmaNo, MI_NDMA_REG_CNT_WOFFSET ) |= MI_NDMA_ENABLE; +} + +/* + 専用NAND関数 +*/ +#define NAND_SECTOR_SIZE 512 +extern void SDCARD_TimerStart(u32 tim); /* タイムアウト計測スタート */ +extern volatile SDMC_ERR_CODE SDCARD_ErrStatus; + +static inline void nandClearFifo( void ) +{ + *SDIF_CNT |= SDIF_CNT_FCLR; +} + +static inline void nandWaitFifoFull( void ) +{ + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ + while( (*SDIF_CNT & SDIF_CNT_FULL) == 0) + { + if ( SDCARD_ErrStatus != SDMC_NORMAL ) // an error was occurred + { + break; + } + } +} + +static void nandStartToRead(u32 block, u32 count) +{ + SD_EnableClock(); + SD_EnableSeccnt(count); + *SDIF_FSC = count; + *SDIF_FDS = NAND_SECTOR_SIZE; + *SDIF_CNT = (*SDIF_CNT & ~SDIF_CNT_FEIE) | SDIF_CNT_FFIE | SDIF_CNT_USEFIFO; + CC_EXT_MODE = CC_EXT_MODE_DMA; + nandClearFifo(); + + SDCARD_ErrStatus = SDMC_NORMAL; + SDCARD_TimerStart(SDCARD_RW_TIMEOUT); /* タイムアウト判定用タイマスタート(2000msec) */ + SD_MultiReadBlock(block * NAND_SECTOR_SIZE); +} + +static void nandStopToRead( void ) +{ + if( !SD_CheckFPGAReg(SD_STOP,SD_STOP_SEC_ENABLE) ){ + SD_StopTransmission(); /* カード転送終了をFPGAに通知(CMD12発行) */ + } + SD_TransEndFPGA(); /* 転送終了処理(割り込みマスクを禁止に戻す) */ + SD_DisableClock(); /* クロック供給停止 */ + + nandClearFifo(); + *SDIF_CNT &= ~SDIF_CNT_USEFIFO; /* FIFO使用フラグOFF */ + CC_EXT_MODE = CC_EXT_MODE_PIO; /* PIOモード(DMAモードOFF) */ +} + +#define AES_GET_CNT_BITS(regValue, name) \ + ((regValue) & (REG_AES_AES_CNT_##name##_MASK)) + +static BOOL useAES = FALSE; + +/*---------------------------------------------------------------------------* + Name: FATFS_EnableAES + + Description: enable AES data path + + Arguments: slot aes key slot number + counter initial counter value + + Returns: None + *---------------------------------------------------------------------------*/ +void FATFS_EnableAES( AESKeySlot slot, const AESCounter* pCounter ) +{ + useAES = TRUE; + AESi_WaitKey(); + AESi_LoadKey( slot ); + AESi_SetCounter( pCounter ); +} + +/*---------------------------------------------------------------------------* + Name: FATFS_DisableAES + + Description: bypass AES + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void FATFS_DisableAES( void ) +{ + useAES = FALSE; +} + +/*---------------------------------------------------------------------------* + Name: nandRead + + Description: normal read + + Arguments: block: source sector number in NAND + dest: dest address (4 bytes alignment) + count: sectors to transfer + + Returns: None + *---------------------------------------------------------------------------*/ +void nandRead(u32 block, void *dest, u16 count) +{ + //MI_StopNDma( DMA_PIPE ); // already stopped + //MI_StopNDma( DMA_RECV ); // already stopped + + nandStartToRead( block, count ); + if ( SDCARD_ErrStatus != SDMC_NORMAL ) + { + return; + } + + while ( count-- ) + { + nandWaitFifoFull(); + MIi_NDmaRecv( DMA_PIPE, (void*)SDIF_FI, dest, NAND_SECTOR_SIZE ); + MI_WaitNDma( DMA_PIPE ); + dest = (void*)((u32)dest + NAND_SECTOR_SIZE); + } + nandStopToRead(); +} + +/*---------------------------------------------------------------------------* + Name: nandReadAES + + Description: AES read + + Arguments: block: source sector number in NAND + dest: dest address (4 bytes alignment) + count: sectors to transfer + + Returns: None + *---------------------------------------------------------------------------*/ +#define PIPE_SIZE 64 +void nandReadAES(u32 block, void *dest, u16 count) +{ + u32 offset = 0; // in bytes + + //MI_StopNDma( DMA_PIPE ); // already stopped + //MI_StopNDma( DMA_RECV ); // already stopped + + MIi_NDmaPipeSetup( DMA_PIPE, (void*)SDIF_FI, (void*)REG_AES_IFIFO_ADDR, PIPE_SIZE ); + +/* + AESのセットアップ&出力DMA設定 +*/ + AESi_Reset(); + AESi_Reset(); + AESi_DmaRecv( DMA_RECV, dest, (u32)(count * NAND_SECTOR_SIZE), NULL, NULL ); +// AESi_SetCounter( &aesCounter ); // remain??? +// FATFSi_AddCounter( count * NAND_SECTOR_SIZE ); // update for next read + AESi_Run( AES_MODE_CTR, 0, (u32)(count * NAND_SECTOR_SIZE / AES_BLOCK_SIZE), NULL, NULL ); + + nandStartToRead( block, count ); + if ( SDCARD_ErrStatus != SDMC_NORMAL ) + { + return; + } + + while ( block * NAND_SECTOR_SIZE > offset ) + { + while ( AES_GET_CNT_BITS( reg_AES_AES_CNT, IFIFO_CNT ) ) + { + } + if ( (offset & NAND_SECTOR_SIZE) == 0 ) + { + nandWaitFifoFull(); + } + MIi_NDmaRestart( DMA_PIPE ); + offset += PIPE_SIZE; + } + MI_WaitNDma( DMA_PIPE ); + nandStopToRead(); + MI_WaitNDma( DMA_RECV ); +} + +/*---------------------------------------------------------------------------* + Name: nandRtfsIoFirm + + Description: 上位層からのセクタリード/ライト要求を受ける + + Arguments: driveno : ドライブ番号 + block : 開始ブロック番号 + buffer : + count : ブロック数 + reading : リード要求時にTRUE + + Returns: TRUE/FALSE + *---------------------------------------------------------------------------*/ +static BOOL nandRtfsIoFirm( int driveno, u32 block, void* buffer, u16 count, BOOL reading) +{ + u16 result; + SdmcResultInfo SdResult; +#pragma unused( driveno) + + /**/ + sdmcSelect( (u16)SDMC_PORT_NAND); + + if( reading) { + if (useAES) + { + nandReadAES(block, buffer, count); + } + else + { + nandRead(block, buffer, count); + } + result = sdmcReadFifo( buffer, count, block, NULL, &SdResult); +// result = sdmcRead( buffer, count, block, NULL, &SdResult); + }else{ + result = sdmcWriteFifo( buffer, count, block, NULL, &SdResult); +// result = sdmcWrite( buffer, count, block, NULL, &SdResult); + } + if( result) { + return FALSE; + } + + return TRUE; +} + +/*---------------------------------------------------------------------------* + Name: nandRtfsAttachFirm + + Description: sdmcドライバをドライブに割り当てる + + Arguments: driveno : ドライブ番号 + + Returns: + *---------------------------------------------------------------------------*/ +#define nandRtfsCtrl FATFSi_nandRtfsCtrl +extern int nandRtfsCtrl( int driveno, int opcode, void* pargs); +static BOOL nandRtfsAttachFirm( int driveno, int partition_no) +{ + BOOLEAN result; + DDRIVE pdr; + + if( partition_no >= NAND_FAT_PARTITION_COUNT) { + return( FALSE); + } + + pdr.dev_table_drive_io = nandRtfsIoFirm; + pdr.dev_table_perform_device_ioctl = nandRtfsCtrl; + pdr.register_file_address = (dword) 0; /* Not used */ + pdr.interrupt_number = 0; /* Not used */ + pdr.drive_flags = (DRIVE_FLAGS_VALID | DRIVE_FLAGS_PARTITIONED);//DRIVE_FLAGS_FAILSAFE; + pdr.partition_number = partition_no; /* Not used */ + pdr.pcmcia_slot_number = 0; /* Not used */ + pdr.controller_number = 0; + pdr.logical_unit_number = 0; + + switch( partition_no) { + case 0: + result = rtfs_attach( driveno, &pdr, "SD1p0"); //構造体がFSライブラリ側にコピーされる + break; + case 1: + result = rtfs_attach( driveno, &pdr, "SD1p1"); //構造体がFSライブラリ側にコピーされる + break; + case 2: + result = rtfs_attach( driveno, &pdr, "SD1p2"); //構造体がFSライブラリ側にコピーされる + break; + case 3: + result = rtfs_attach( driveno, &pdr, "SD1p3"); //構造体がFSライブラリ側にコピーされる + break; + default: + result = FALSE; + break; + } + + return( result); +} + +/*---------------------------------------------------------------------------* + Name: FATFS_InitFIRM + + Description: init file system + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +extern SDMC_ERR_CODE sdmcNandInit( void (*func1)(),void (*func2)()); +BOOL FATFS_InitFIRM( void ) +{ + /* RTFSライブラリを初期化 */ + if(!rtfs_init()) + { + return FALSE; + } + + /* SDドライバ初期化 */ +// if (sdmcInit(SDMC_NOUSE_DMA, NULL, NULL) != SDMC_NORMAL) // firm_sdmc + if (sdmcNandInit(NULL, NULL) != SDMC_NORMAL) // rom_sdmc + { + return FALSE; + } + return TRUE; +} + +/*---------------------------------------------------------------------------* + Name: FATFS_MountNandFirm + + Description: mount nand partition + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +BOOL FATFS_MountNandFirm( int driveno, int partition_no ) +{ + // CAUTION!: 同じ関数を2回呼び出す理由について要確認。 + if ( !nandRtfsAttachFirm(driveno, partition_no) || nandRtfsAttachFirm(driveno, partition_no)) + { + return FALSE; + } + return TRUE; +} diff --git a/build/libraries/fatfs/ARM7/src/fatfs_loader.c b/build/libraries/fatfs/ARM7/src/fatfs_loader.c new file mode 100644 index 00000000..c18e5f04 --- /dev/null +++ b/build/libraries/fatfs/ARM7/src/fatfs_loader.c @@ -0,0 +1,242 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - libraries - fatfs + File: fatfs_loader.c + + Copyright 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. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include + +#include +#include +#include +#include +#include +#include + +#define PXI_FIFO_TAG_DATA PXI_FIFO_TAG_USER_0 + +static ROM_Header* const rh= (ROM_Header*)(HW_MAIN_MEM_SYSTEM_END - 0x2000); +static int menu_fd = 0; + +/*---------------------------------------------------------------------------* + Name: FATFS_OpenRecentMenu + + Description: open recent menu file + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +BOOL FATFS_OpenRecentMenu( int driveno ) +{ + char menufile[] = "A:\\ipl\\menu.srl"; + if (driveno < 0 || driveno >= 26) + { + return FALSE; + } + menufile[0] = (char)('A' + driveno); + menu_fd = po_open((u8*)menufile, PO_BINARY, 0); + if (menu_fd <= 0) + { + return FALSE; + } + return TRUE; +} + +#define HEADER_SIZE 0x1000 + +#define SLOT_SIZE 0x2000 + +static BOOL FATFS_LoadBuffer(u32 offset, u32 size) +{ + u8* base = (u8*)MI_GetWramMapStart_B(); + u8* curr = base; + static int count = 0; + + // seek first + if (!po_lseek(menu_fd, (s32)offset, PSEEK_SET)) + { + return FALSE; + } + // loading loop + while (size > 0) + { + u8* dest = curr + count * SLOT_SIZE; // target buffer address + u32 unit = size < SLOT_SIZE ? size : SLOT_SIZE; // size + while (MI_GetWramBankMaster_B(count) != MI_WRAM_ARM7) // waiting to be master + { + } + if (!po_read(menu_fd, (u8*)dest, (int)unit)) // reading + { + return FALSE; + } + PXI_NotifyID( FIRM_PXI_ID_LOAD_PIRIOD ); + count = (count + 1) & 0x7; + size -= unit; + } + return TRUE; +} + +/*---------------------------------------------------------------------------* + Name: FATFS_LoadHeader + + Description: load menu header + + Arguments: None + + Returns: TRUE if success + *---------------------------------------------------------------------------*/ +BOOL FATFS_LoadHeader( void ) +{ + // open the file in FATFS_InitFIRM() + if (menu_fd <= 0) + { + return FALSE; + } + + // load header without AES + PXI_NotifyID( FIRM_PXI_ID_LOAD_HEADER ); + FATFS_DisableAES(); + if (!FATFS_LoadBuffer(0, HEADER_SIZE) || + PXI_RecvID() != FIRM_PXI_ID_AUTH_HEADER ) + { + return FALSE; + } + + // set id depends on game_code and seed to use (or all?) + { + AESKeySeed seed; + AESi_InitGameKeys((u8*)rh->s.game_code); + PXI_RecvDataByFifo( PXI_FIFO_TAG_DATA, &seed, AES_BLOCK_SIZE ); + AESi_SetKeySeedA(&seed); // APP + //AESi_SetKeySeedB(&seed); // APP & HARD + //AESi_SetKeySeedC(&seed); // + //AESi_SetKeySeedD(&seed); // HARD + } + + return TRUE; +} + +static void FATFSi_AddCounter(AESCounter* pCounter, u32 nums) +{ + u32 data = 0; + int i; + for (i = 15; i >= 0; i--) + { + data += pCounter->bytes[i] + (nums & 0xFF); + pCounter->bytes[i] = (u8)(data & 0xFF); + data >>= 8; + nums >>= 8; + if ( !data && !nums ) + { + break; + } + } +} + +static AESCounter* FATFSi_GetCounter( u32 offset ) +{ + static AESCounter counter; + MI_CpuCopy8(rh->s.main_static_digest, &counter, 12); + counter.words[3] = 0; + FATFSi_AddCounter(&counter, offset - SECURE_AREA_START); + return &counter; +} + + +/*---------------------------------------------------------------------------* + Name: FATFS_LoadMenu + + Description: load menu binary + + Arguments: None + + Returns: TRUE if success + *---------------------------------------------------------------------------*/ +BOOL FATFS_LoadMenu( void ) +{ + // load ARM9 static region without AES + if ( rh->s.main_size > 0 ) + { + PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM9_STATIC ); + FATFS_DisableAES(); + if ( !FATFS_LoadBuffer( rh->s.main_rom_offset, rh->s.main_size ) || + PXI_RecvID() != FIRM_PXI_ID_AUTH_ARM9_STATIC ) + { + return FALSE; + } + } + // load ARM7 static region without AES + if ( rh->s.sub_size > 0 ) + { + PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM7_STATIC ); + FATFS_DisableAES(); + if ( !FATFS_LoadBuffer( rh->s.sub_rom_offset, rh->s.sub_size ) || + PXI_RecvID() != FIRM_PXI_ID_AUTH_ARM7_STATIC ) + { + return FALSE; + } + } + // load ARM9 extended static region with AES + if ( rh->s.main_ex_size > 0 ) + { + PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM9_STATIC_EX ); + if ( !rh->s.enable_aes || !rh->s.enable_signature ) + { + FATFS_DisableAES(); + } + else + { + FATFS_EnableAES( AES_KEY_SLOT_A, FATFSi_GetCounter( rh->s.main_ex_rom_offset ) ); + } + if ( !FATFS_LoadBuffer( rh->s.main_ex_rom_offset, rh->s.main_ex_size ) || + PXI_RecvID() != FIRM_PXI_ID_AUTH_ARM9_STATIC_EX ) + { + return FALSE; + } + } + // load ARM7 extended static region with AES + if ( rh->s.sub_ex_size > 0 ) + { + PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM7_STATIC_EX ); + if ( !rh->s.enable_aes || !rh->s.enable_signature ) + { + FATFS_DisableAES(); + } + else + { + FATFS_EnableAES( AES_KEY_SLOT_A, FATFSi_GetCounter( rh->s.sub_ex_rom_offset ) ); + } + if ( !FATFS_LoadBuffer( rh->s.sub_ex_rom_offset, rh->s.sub_ex_size ) || + PXI_RecvID() != FIRM_PXI_ID_AUTH_ARM7_STATIC_EX ) + { + return FALSE; + } + } + return TRUE; +} + +/*---------------------------------------------------------------------------* + Name: FATFS_BootMenu + + Description: boot menu + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void FATFS_BootMenu( void ) +{ + OSi_Boot( rh->s.sub_entry_address, (MIHeader_WramRegs*)rh->s.main_wram_config_data ); +} diff --git a/build/libraries/fatfs/Makefile b/build/libraries/fatfs/Makefile new file mode 100644 index 00000000..2f6bc992 --- /dev/null +++ b/build/libraries/fatfs/Makefile @@ -0,0 +1,31 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlIPL - libraries - fatfs +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = ARM7 + +#---------------------------------------------------------------------------- + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/libraries/mi/ARM9/Makefile b/build/libraries/mi/ARM9/Makefile index 17a24289..23dc414c 100644 --- a/build/libraries/mi/ARM9/Makefile +++ b/build/libraries/mi/ARM9/Makefile @@ -29,6 +29,7 @@ SRCDIR = . SRCS = \ mi_init_mainMemory.c \ + mi_loader.c \ TARGET_LIB = libmi$(FIRM_LIBSUFFIX).a diff --git a/build/libraries/os/common/os_boot.c b/build/libraries/os/common/os_boot.c index fe002924..fb449446 100644 --- a/build/libraries/os/common/os_boot.c +++ b/build/libraries/os/common/os_boot.c @@ -16,10 +16,58 @@ *---------------------------------------------------------------------------*/ #include #include +#include #ifdef SDK_ARM9 #include +#else +#include #endif +void OSi_BootCore( OSEntryPoint p ); + +/*---------------------------------------------------------------------------* + Name: OSi_Boot + + Description: boot firm + + Arguments: entry : entry point + w : wram settings + + Returns: None + *---------------------------------------------------------------------------*/ +void OSi_Boot( void* entry, MIHeader_WramRegs* w ) +{ + OSEntryPoint p = (OSEntryPoint)entry; + + (void)OS_DisableInterrupts(); + OSi_Finalize(); + +#ifdef SDK_ARM9 + + MI_CpuCopy8( w, (void*)REG_MBK1_ADDR, 32 ); // set MBK1 - 8 + //reg_RBKCNT1_H_ADDR = w->sub_wramlock[4]; // set RBKCNT01 + + // request hiding secure rom + PXI_NotifyID( FIRM_PXI_ID_DONE_WRAM_SETTING ); + + OSi_ClearWorkArea(); + +#else // SDK_ARM7 + + // wait request of hiding secure rom + PXI_WaitID( FIRM_PXI_ID_DONE_WRAM_SETTING ); + + MI_CpuCopy8( &w->sub_wrammap_a, (void*)REG_MBK6_ADDR, 13 ); // set MBK6 - MBK_C_LOCK + + AESi_SetKeySeedA( (AESKeySeed*)OSi_GetFromBromAddr()->aes_key[2] ); // erase + + OSi_ClearWorkArea(); + +#endif // SDK_ARM7 + + OSi_BootCore( p ); +} + /*---------------------------------------------------------------------------* Name: OSi_Finalize @@ -55,3 +103,52 @@ void OSi_Finalize(void) #endif // SDK_ARM9 } +extern void SDK_STATIC_DATA_START(void); // static data start address +extern void SDK_STATIC_BSS_END(void); // static bss end address + +/*---------------------------------------------------------------------------* + Name: OSi_ClearWorkArea + + Description: clear work area + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +#include +asm void OSi_ClearWorkArea( void ) +{ + mov r11, lr + + // clear stack with r4-r9 + mov r0, #0 + ldr r1, =SDK_STATIC_DATA_START + ldr r2, =SDK_STATIC_BSS_END + sub r2, r2, r1 + bl MIi_CpuClearFast + + bx r11 +} + +asm void OSi_BootCore( OSEntryPoint p ) +{ + mov r11, r0 + + // clear stack with r4-r9 + mov r0, #0 +#if 0 + ldr r1, =HW_FIRM_STACK + ldr r2, =HW_FIRM_STACK_SIZE +#endif + bl MIi_CpuClearFast + + mov lr, r11 + + // clear registers +#if 0 + ldr sp, =HW_FIRM_STACK +#endif + ldmia sp, {r0-r12,sp} + + bx lr +} diff --git a/build/libraries/os/common/os_init_firm.c b/build/libraries/os/common/os_init_firm.c index 5f6745e2..611549b3 100644 --- a/build/libraries/os/common/os_init_firm.c +++ b/build/libraries/os/common/os_init_firm.c @@ -40,14 +40,14 @@ void OS_InitFIRM(void) OS_InitPrintServer(); #endif - //---- Init Arena (arenas except SUBPRIV-WRAM) - OS_InitArena(); - //---- Init interProcessor I/F // Sync with ARM7 to enable OS_GetConsoleType() // PXI_Init() must be called before OS_InitArenaEx() PXI_Init(); + //---- Init Arena (arenas except SUBPRIV-WRAM) + OS_InitArena(); + //---- Init Spinlock OS_InitLock(); @@ -103,12 +103,12 @@ void OS_InitFIRM(void) //---------------------------------------------------------------- // for ARM7 - //---- Init Arena (SUBPRIV-WRAM arena) - OS_InitArena(); - //---- Init interProcessor I/F PXI_Init(); + //---- Init Arena (SUBPRIV-WRAM arena) + OS_InitArena(); + //---- Init Spinlock OS_InitLock(); diff --git a/build/libraries/pm/ARM7/Makefile b/build/libraries/pm/ARM7/Makefile new file mode 100644 index 00000000..03187580 --- /dev/null +++ b/build/libraries/pm/ARM7/Makefile @@ -0,0 +1,62 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - libraries - pm +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +SUBDIRS = +SUBMAKES = + + +#---------------------------------------------------------------------------- + +# build ARM & THUMB libraries +FIRM_CODEGEN_ALL ?= TRUE + +# Codegen for sub processer +FIRM_PROC = ARM7 + +INCDIR = $(TWLSDK_ROOT)/build/libraries/spi/ARM7/pm/include \ + +SRCDIR = . + +SRCS = \ + pm_init.c \ + pm_pmic_ex.c \ + +TARGET_LIB = libpm_sp$(FIRM_LIBSUFFIX).a + +#---------------------------------------------------------------------------- + +# DEBUG版ビルドの場合、RELEASE版でビルドして +# DEBUG版のライブラリを装います。 + +ifdef NITRO_DEBUG +NITRO_BUILD_TYPE = RELEASE +endif + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_TARGETS = $(TARGETS) +INSTALL_DIR = $(FIRM_INSTALL_LIBDIR) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + +#===== End of Makefile ===== diff --git a/build/libraries/pm/ARM7/pm_init.c b/build/libraries/pm/ARM7/pm_init.c new file mode 100644 index 00000000..d270fa85 --- /dev/null +++ b/build/libraries/pm/ARM7/pm_init.c @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - libraries - pm + File: pm_init.c + + Copyright 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. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#include + +#define OS_MSEC_TO_CPUCYC( msec ) ((u32)( ((HW_CPU_CLOCK/1000) * (u32)(msec)) )) + +/*---------------------------------------------------------------------------* + Name: PM_InitFIRM + + Description: power B/L on + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void PM_InitFIRM( void ) +{ + // LED + PMi_ResetFlags( REG_PMIC_LED_CTL_ADDR, PMIC_LED_CTL_L12_AT_BLK | PMIC_LED_CTL_L12_BLK_BY_SLP ); + PMi_SetParams( REG_PMIC_LED12_B4_ADDR, + PMIC_LED12_B4_L1_100 | PMIC_LED12_B4_L2_100, + PMIC_LED12_B4_L1_MASK | PMIC_LED12_B4_L2_MASK + ); + PMi_SetParams( REG_PMIC_LED12_B3_ADDR, + PMIC_LED12_B3_L1_OFF | PMIC_LED12_B3_L2_100, + PMIC_LED12_B3_L1_MASK | PMIC_LED12_B3_L2_MASK + ); + PMi_SetParams( REG_PMIC_LED12_B2_ADDR, + PMIC_LED12_B2_L1_100 | PMIC_LED12_B2_L2_OFF, + PMIC_LED12_B2_L1_MASK | PMIC_LED12_B2_L2_MASK + ); + PMi_SetParams( REG_PMIC_LED12_B1_ADDR, + PMIC_LED12_B1_L1_OFF | PMIC_LED12_B1_L2_OFF, + PMIC_LED12_B1_L1_MASK | PMIC_LED12_B1_L2_MASK + ); + + // LCD ON + PMi_SetFlags( REG_PMIC_CTL2_ADDR, PMIC_CTL2_LCD_PWR ); + + // back light ON + PMi_SetParams( REG_PMIC_BL1_BRT_ADDR, PMIC_BL_BRT_MAX, PMIC_BL1_BRT_MASK ); + PMi_SetParams( REG_PMIC_BL2_BRT_ADDR, PMIC_BL_BRT_MAX, PMIC_BL2_BRT_MASK ); + OS_SpinWait( OS_MSEC_TO_CPUCYC( 17*2 ) ); + PMi_SetFlags( REG_PMIC_CTL2_ADDR, PMIC_CTL2_BKLT1 | PMIC_CTL2_BKLT2 ); +} diff --git a/build/libraries/pm/ARM7/pm_pmic_ex.c b/build/libraries/pm/ARM7/pm_pmic_ex.c new file mode 100644 index 00000000..5932fa03 --- /dev/null +++ b/build/libraries/pm/ARM7/pm_pmic_ex.c @@ -0,0 +1,72 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - libraries - pm + File: pm_pmic_ex.c + + Copyright 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#include +#include + +//================================================================================ +// PMIC BIT CONTROL +//================================================================================ +/*---------------------------------------------------------------------------* + Name: PMi_SetParams + + Description: set control bit to device register + + Arguments: reg : device register + setBits : bits to set + maskBits : bits to mask + + Returns: None + *---------------------------------------------------------------------------*/ +void PMi_SetParams( u8 reg, u8 setBits, u8 maskBits ) +{ + u8 tmp; + tmp = PMi_GetRegister( reg ); + tmp &= ~maskBits; + setBits &= maskBits; + tmp |= setBits; + PMi_SetRegister( reg, tmp ); +} + +/*---------------------------------------------------------------------------* + Name: PMi_SetFlags + + Description: set control bit to device register + + Arguments: reg : device register + setBits : bits to set + + Returns: None + *---------------------------------------------------------------------------*/ +void PMi_SetFlags( u8 reg, u8 setBits ) +{ + PMi_SetParams( reg, setBits, setBits ); +} + +/*---------------------------------------------------------------------------* + Name: PMi_ResetFlags + + Description: clear control bit to device register + + Arguments: reg : device register + clrBits : bits to set + + Returns: None + *---------------------------------------------------------------------------*/ +void PMi_ResetFlags( u8 reg, u8 clrBits ) +{ + PMi_SetParams( reg, 0, clrBits ); +} + diff --git a/build/libraries/pm/Makefile b/build/libraries/pm/Makefile new file mode 100644 index 00000000..e9849a40 --- /dev/null +++ b/build/libraries/pm/Makefile @@ -0,0 +1,31 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlIPL - libraries - pm +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = ARM7 + +#---------------------------------------------------------------------------- + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/libraries/pxi/ARM7/Makefile b/build/libraries/pxi/ARM7/Makefile new file mode 100644 index 00000000..abd1828a --- /dev/null +++ b/build/libraries/pxi/ARM7/Makefile @@ -0,0 +1,61 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - libraries_sp - pxi +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +SUBDIRS = +#SUBMAKES = Makefile.CALLTRACE \ +# Makefile.FUNCTIONCOST + +#---------------------------------------------------------------------------- + +# build ARM & THUMB libraries +FIRM_CODEGEN_ALL ?= TRUE + +# Codegen for sub processer +FIRM_PROC = ARM7 + +SRCDIR = ../common . + +SRCS = \ + pxi_misc.c \ + +TARGET_LIB = libpxi_sp$(FIRM_LIBSUFFIX).a + + +#---------------------------------------------------------------------------- + +# DEBUG版ビルドの場合、RELEASE版でビルドして +# DEBUG版のライブラリを装います。 + +ifdef NITRO_DEBUG +NITRO_BUILD_TYPE = RELEASE +endif + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_TARGETS = $(TARGETS) +INSTALL_DIR = $(FIRM_INSTALL_LIBDIR) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/libraries/pxi/ARM9/Makefile b/build/libraries/pxi/ARM9/Makefile new file mode 100644 index 00000000..25bdcdf3 --- /dev/null +++ b/build/libraries/pxi/ARM9/Makefile @@ -0,0 +1,58 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - libraries - pxi +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +SUBDIRS = +SUBMAKES = + + +#---------------------------------------------------------------------------- + +# build ARM & THUMB libraries +FIRM_CODEGEN_ALL ?= TRUE + +SRCDIR = ../common . + +SRCS = \ + pxi_misc.c \ + +TARGET_LIB = libpxi$(FIRM_LIBSUFFIX).a + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_TARGETS = $(TARGETS) +INSTALL_DIR = $(FIRM_INSTALL_LIBDIR) + +ifdef NITRO_CALLTRACE +CCFLAGS += -DOS_PROFILE_AVAILABLE -DOS_PROFILE_CALL_TRACE +endif + +ifdef NITRO_FUNCTIONCOST +CCFLAGS += -DOS_PROFILE_AVAILABLE -DOS_PROFILE_FUNCTION_COST +endif + +ifdef NITRO_TCM_APPLY +CCFLAGS += -DSDK_TCM_APPLY +endif + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + +#===== End of Makefile ===== diff --git a/build/libraries/pxi/Makefile b/build/libraries/pxi/Makefile new file mode 100644 index 00000000..29d6aa7d --- /dev/null +++ b/build/libraries/pxi/Makefile @@ -0,0 +1,32 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - libraries - pxi +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = ARM9 \ + ARM7 \ + +#---------------------------------------------------------------------------- + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/libraries/pxi/common/pxi_misc.c b/build/libraries/pxi/common/pxi_misc.c new file mode 100644 index 00000000..7804e4b5 --- /dev/null +++ b/build/libraries/pxi/common/pxi_misc.c @@ -0,0 +1,352 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - library - pxi + File: pxi_misc.c + + Copyright 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ +#include +#include +#include + +static u16 FifoCtrlInit = 0; + +/*********** function prototypes ******************/ +static inline PXIFifoStatus PXIi_GetFromFifo(u32 *data_buf); +static inline PXIFifoStatus PXIi_SetToFifo(u32 data); + + +/*---------------------------------------------------------------------------* + Name: PXI_InitFifoFIRM + + Description: initialize FIFO system for firm + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void PXI_InitFifoFIRM(void) +{ + OSIntrMode enabled; + + enabled = OS_DisableInterrupts(); + + if (!FifoCtrlInit) + { + FifoCtrlInit = TRUE; + + reg_PXI_FIFO_CNT = + (REG_PXI_FIFO_CNT_SEND_CL_MASK | + REG_PXI_FIFO_CNT_E_MASK | REG_PXI_FIFO_CNT_ERR_MASK); + +#ifdef SDK_ARM9 + PXI_SendIDByIntf( FIRM_PXI_ID_INIT_ARM9 ); + PXI_WaitIDByIntf( FIRM_PXI_ID_INIT_ARM7 ); +#else // SDK_ARM7 + PXI_SendIDByIntf( FIRM_PXI_ID_INIT_ARM7 ); + PXI_WaitIDByIntf( FIRM_PXI_ID_INIT_ARM9 ); +#endif // SDK_ARM7 + } + (void)OS_RestoreInterrupts(enabled); +} + + +/*---------------------------------------------------------------------------* + Name: PXI_NotifyID + + Description: Send 4bit id to other processor + + Arguments: id notifying id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_NotifyID( u32 id ) +{ + PXI_SendIDByFifo( PXI_FIFO_TAG_SYSTEM, id ); +} + +/*---------------------------------------------------------------------------* + Name: PXI_WaitID + + Description: Wait 4bit id from the other processor + + Arguments: id waiting id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_WaitID( u32 id ) +{ + PXI_WaitIDByFifo( PXI_FIFO_TAG_SYSTEM, id ); +} + +/*---------------------------------------------------------------------------* + Name: PXI_RecvID + + Description: Receive 4bit id from the other processor + + Arguments: None + + Returns: id + *---------------------------------------------------------------------------*/ +u8 PXI_RecvID( void ) +{ + u8 id; + + while (PXI_RecvIDByFifo(PXI_FIFO_TAG_SYSTEM, &id) != PXI_FIFO_SUCCESS) + { + } + + return id; +} + +/*---------------------------------------------------------------------------* + Name: PXI_SendIDByIntf + + Description: Send 4bit id to the other processor + + Arguments: id sending id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_SendIDByIntf( u32 id ) +{ + reg_PXI_INTF = (u16)(id << REG_PXI_INTF_SEND_SHIFT); +} + +/*---------------------------------------------------------------------------* + Name: PXI_RecvIDByIntf + + Description: Receive 4bit id from the other processor + + Arguments: None + + Returns: received id + *---------------------------------------------------------------------------*/ +u32 PXI_RecvIDByIntf( void ) +{ + return (u32)((reg_PXI_INTF & REG_PXI_INTF_RECV_MASK) >> REG_PXI_INTF_RECV_SHIFT); +} + +/*---------------------------------------------------------------------------* + Name: PXI_WaitIDByIntf + + Description: Wait 4bit id from the other processor + + Arguments: id waiting id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_WaitIDByIntf( u32 id ) +{ + while (PXI_RecvIDByIntf() != id) + { + } +} + +/*---------------------------------------------------------------------------* + Name: PXI_SendIDByFifo + + Description: Send 32bit-word to another CPU via FIFO + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_SendIDByFifo(PXIFifoTag tag, u32 id) +{ + static PXIFifoMessage fifomsg; + + fifomsg.e.tag = tag; + fifomsg.e.data = id; + + while ( PXIi_SetToFifo(fifomsg.raw) != PXI_FIFO_SUCCESS ) + { + } +} + +/*---------------------------------------------------------------------------* + Name: PXI_RecvIDByFifo + + Description: Recv 32bit-word from another CPU via FIFO + + Arguments: + + Returns: if error occured, returns minus value + *---------------------------------------------------------------------------*/ +PXIFifoStatus PXI_RecvIDByFifo(PXIFifoTag tag, void* buf) +{ + static PXIFifoMessage fifomsg; + u8* p = buf; + + while ( PXIi_GetFromFifo(&fifomsg.raw) != PXI_FIFO_SUCCESS ) + { + } + + if (fifomsg.e.tag != tag) + { + return PXI_FIFO_FAIL_RECV_ERR; + } + + *p = (u8)fifomsg.e.data; + + return PXI_FIFO_SUCCESS; +} + +/*---------------------------------------------------------------------------* + Name: PXI_WaitIDByFifo + + Description: Wait 32bit-word from another CPU via FIFO + + Arguments: id waiting id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_WaitIDByFifo(PXIFifoTag tag, u32 id) +{ + u8 buf = (u8)id; + + do + { + while (PXI_RecvIDByFifo(tag, &buf) != PXI_FIFO_SUCCESS) + { + } + } + while ( buf != id ); +} + +/*---------------------------------------------------------------------------* + Name: PXI_SendDataByFifo + + Description: Send data to another CPU via FIFO + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_SendDataByFifo(PXIFifoTag tag, void* buf, int size) +{ + static PXIFifoMessage fifomsg; + u32* p = buf; + int len = size/4; + int i; + + fifomsg.e.tag = tag; + fifomsg.e.data = len; + + while ( PXIi_SetToFifo(fifomsg.raw) != PXI_FIFO_SUCCESS ) + { + } + + for ( i=0; i max_size/4) + { + return PXI_FIFO_FAIL_SEND_ERR; + } + + for ( i=0; i +#include +#include + +#define FIRM_ENABLE_JTAG + +#define DRIVE_LETTER 'A' // マウント先ドライブ名 +#define DRIVE_NO (DRIVE_LETTER - 'A') // マウント先ドライブ番号 +#define PARTITION_NO 0 // 対象パーティション + +void TwlSpMain( void ) +{ + OS_TPrintf( "\nNAND Boot time is %d msec.\n", OS_TicksToMilliSecondsBROM32(OS_GetTick())); + +// for normal program +// MIi_CpuClearFast( 0, (void*)OSi_GetFromBromAddr(), sizeof(OSFromBromBuf) ); + +// required here? +// reg_GX_VRAMCNT_C = REG_GX_VRAMCNT_C_FIELD( TRUE, 0, 0x2); + + OS_InitFIRM(); + + OS_InitDebugLED(); + OS_SetDebugLED(0x01); + +#ifdef FIRM_ENABLE_JTAG + reg_SCFG_JTAG = REG_SCFG_JTAG_CPUJE_MASK | REG_SCFG_JTAG_ARM7SEL_MASK; +#endif // FIRM_ENABLE_JTAG + + PM_InitFIRM(); + + OS_SetDebugLED(0x02); + + // load menu + if ( FATFS_InitFIRM() && // ARM7側のみ&NANDのみ + FATFS_MountNandFirm(DRIVE_NO, PARTITION_NO) && // NAND[0]をX:ドライブにマウント + FATFS_OpenRecentMenu(DRIVE_NO) ) // 目的のファイルをオープンしてしまう + { + + OS_SetDebugLED(0x04); + + if ( FATFS_LoadHeader() && FATFS_LoadMenu() ) + { + + OS_SetDebugLED(0x08); + + FATFS_BootMenu(); + } + } + else + { + PXI_NotifyID( FIRM_PXI_ID_NULL ); + } + + OS_SetDebugLED(0xF0); + + OS_Terminate(); +} + diff --git a/build/nandfirm/nandfirm-loader/ARM9/Makefile b/build/nandfirm/nandfirm-loader/ARM9/Makefile new file mode 100644 index 00000000..ab735d1e --- /dev/null +++ b/build/nandfirm/nandfirm-loader/ARM9/Makefile @@ -0,0 +1,48 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - tools - nandfirm-loader +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +FIRM_TARGET = FIRM + +SUBDIRS = + +LINCLUDES = ../include + +#---------------------------------------------------------------------------- + +TARGET_BIN = twl_nandfirm9_loader.axf + +SRCS = main.c + +CRT0_O = crt0_firm.o + +#SRCDIR = # using default +#LCFILE = # using default + + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/nandfirm/nandfirm-loader/ARM9/main.c b/build/nandfirm/nandfirm-loader/ARM9/main.c new file mode 100644 index 00000000..79c7c549 --- /dev/null +++ b/build/nandfirm/nandfirm-loader/ARM9/main.c @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - nandfirm - nandrfirm-loader + File: main.c + + Copyright 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. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ +#include +#include + +u8 acHeap[4*1024] __attribute__ ((aligned (32))); +int acPool[3]; +int errID; + +void TwlMain( void ) +{ + OS_TPrintf( "\nNAND Boot time is %d msec.\n", OS_TicksToMilliSecondsBROM32(OS_GetTick())); + + OS_InitFIRM(); + + SVC_InitSignHeap( acPool, acHeap, sizeof(acHeap) ); + + // load menu + if ( MI_LoadHeader( acPool ) && MI_LoadMenu() ) + { + MI_BootMenu(); + } + + OS_Terminate(); + +} + diff --git a/build/nandfirm/nandfirm-loader/Makefile b/build/nandfirm/nandfirm-loader/Makefile new file mode 100644 index 00000000..f08837d2 --- /dev/null +++ b/build/nandfirm/nandfirm-loader/Makefile @@ -0,0 +1,54 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - build +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + + +FIRM_TARGET = FIRM + + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + + +#---------------------------------------------------------------------------- + +SUBDIRS = \ + ARM7 \ + ARM9 \ + wram_regs \ + +TARGET_FIRM_BIN = nandfirm_loader.nand +BINDIR = . +MAKEFIRM_ARM9 = ARM9/bin/ARM9-$(FIRM_PLATFORM)$(CODEGEN_ARCH)/$(FIRM_BUILD_DIR)/twl_nandfirm9_loader.axf +MAKEFIRM_ARM7 = ARM7/bin/ARM7-$(FIRM_PLATFORM)$(CODEGEN_ARCH)/$(FIRM_BUILD_DIR)/twl_nandfirm7_loader.axf +MAKEFIRM_RSA_PRVKEY = $(TWL_KEYSDIR)/rsa/private_nand.der +LDEPENDS_BIN += wram_regs/wram_regs.rbin + +NITRO_MAKEROM = TRUE +MAKEFIRM_FLAGS += -p +FIRM_SPEC = nandfirm.nandsf + +LDIRT_CLEAN += $(BINDIR)/$(TARGET_BIN) \ + rsa_public.sbin \ + +#---------------------------------------------------------------------------- + +do-build: $(TARGET_BIN) + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/nandfirm/nandfirm-loader/nandfirm.nandsf b/build/nandfirm/nandfirm-loader/nandfirm.nandsf new file mode 100644 index 00000000..2f3f059d --- /dev/null +++ b/build/nandfirm/nandfirm-loader/nandfirm.nandsf @@ -0,0 +1,24 @@ +#NANDSF --- Nandfirm Spec File + +VERSION : GENERATE + +RSA_KEY : $(MAKEFIRM_RSA_PRVKEY) +OUT_KEY : rsa_public.sbin + +WRAM_RBIN: ./wram_regs/wram_regs.rbin + +MIRROR_OFS: 0x80000 + +DECOMP_PROC : ARM9 # ARM9 or ARM7 + +ARM9_COMP : FALSE # TRUE or FALSE, should be before ARM9_SBIN +ARM9_SBIN : $(MAKEFIRM_ARM9).FLX.TWL.sbin +ARM9_ELF : $(MAKEFIRM_ARM9).axf + +ARM7_COMP : FALSE # TRUE or FALSE, should be before ARM7_SBIN +ARM7_SBIN : $(MAKEFIRM_ARM7).FLX.TWL.sbin +ARM7_ELF : $(MAKEFIRM_ARM7).axf + +ARM9_X2 : TRUE # TRUE or FALSE + +NCD_ROMOFS : 0x07fe00 diff --git a/build/nandfirm/nandfirm-loader/wram_regs/Makefile b/build/nandfirm/nandfirm-loader/wram_regs/Makefile new file mode 100644 index 00000000..3ca1913a --- /dev/null +++ b/build/nandfirm/nandfirm-loader/wram_regs/Makefile @@ -0,0 +1,48 @@ +#! make -f +#---------------------------------------------------------------------------- +# Project: TwlFirm - tools - norfirm-print +# File: Makefile +# +# Copyright 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. +# +# $Date:: $ +# $Rev:$ +# $Author:$ +#---------------------------------------------------------------------------- + +SUBDIRS = + +LINCLUDES = ../include + +#---------------------------------------------------------------------------- + +TARGET_BIN = wram_regs.rbin + +SRCS = \ + wram_regs.c \ + +#SRCDIR = # using default +#LCFILE = # using default + + +include $(TWLFIRM_ROOT)/build/buildtools/commondefs + +INSTALL_DIR = . +INSTALL_TARGETS = $(BINDIR)/$(TARGET_BIN) + + +#---------------------------------------------------------------------------- + +do-build: $(TARGETS) + + +include $(TWLFIRM_ROOT)/build/buildtools/modulerules + + +#===== End of Makefile ===== diff --git a/build/nandfirm/nandfirm-loader/wram_regs/wram_regs.c b/build/nandfirm/nandfirm-loader/wram_regs/wram_regs.c new file mode 100644 index 00000000..995edeca --- /dev/null +++ b/build/nandfirm/nandfirm-loader/wram_regs/wram_regs.c @@ -0,0 +1,91 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - tools - nandfirm + File: wram_regs.c + + Copyright 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. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ +#include +#include + +MIHeader_WramRegs wram_regs_init = +{ + // ARM9 + { + REG_MI_MBK_A0_FIELD( 1, MI_WRAM_A_OFFSET_0KB , MI_WRAM_ARM7 ), + REG_MI_MBK_A1_FIELD( 1, MI_WRAM_A_OFFSET_64KB , MI_WRAM_ARM7 ), + REG_MI_MBK_A2_FIELD( 1, MI_WRAM_A_OFFSET_128KB, MI_WRAM_ARM7 ), + REG_MI_MBK_A3_FIELD( 1, MI_WRAM_A_OFFSET_192KB, MI_WRAM_ARM7 ), + }, + { + REG_MI_MBK_B0_FIELD( 1, MI_WRAM_BC_OFFSET_0KB , MI_WRAM_ARM7 ), + REG_MI_MBK_B1_FIELD( 1, MI_WRAM_BC_OFFSET_32KB , MI_WRAM_ARM7 ), + REG_MI_MBK_B2_FIELD( 1, MI_WRAM_BC_OFFSET_64KB , MI_WRAM_ARM7 ), + REG_MI_MBK_B3_FIELD( 1, MI_WRAM_BC_OFFSET_96KB , MI_WRAM_ARM7 ), + REG_MI_MBK_B4_FIELD( 1, MI_WRAM_BC_OFFSET_128KB, MI_WRAM_ARM7 ), + REG_MI_MBK_B5_FIELD( 1, MI_WRAM_BC_OFFSET_160KB, MI_WRAM_ARM7 ), + REG_MI_MBK_B6_FIELD( 1, MI_WRAM_BC_OFFSET_192KB, MI_WRAM_ARM7 ), + REG_MI_MBK_B7_FIELD( 1, MI_WRAM_BC_OFFSET_224KB, MI_WRAM_ARM7 ), + }, + { + REG_MI_MBK_C0_FIELD( 1, MI_WRAM_BC_OFFSET_0KB , MI_WRAM_ARM9 ), + REG_MI_MBK_C1_FIELD( 1, MI_WRAM_BC_OFFSET_32KB , MI_WRAM_ARM9 ), + REG_MI_MBK_C2_FIELD( 1, MI_WRAM_BC_OFFSET_64KB , MI_WRAM_ARM9 ), + REG_MI_MBK_C3_FIELD( 1, MI_WRAM_BC_OFFSET_96KB , MI_WRAM_ARM9 ), + REG_MI_MBK_C4_FIELD( 1, MI_WRAM_BC_OFFSET_128KB, MI_WRAM_ARM9 ), + REG_MI_MBK_C5_FIELD( 1, MI_WRAM_BC_OFFSET_160KB, MI_WRAM_ARM9 ), + REG_MI_MBK_C6_FIELD( 1, MI_WRAM_BC_OFFSET_192KB, MI_WRAM_ARM9 ), + REG_MI_MBK_C7_FIELD( 1, MI_WRAM_BC_OFFSET_224KB, MI_WRAM_ARM9 ), + }, + REG_MI_MBK6_FIELD( REG_WRAM_MAP_CONV_ADDR( 6, A, EADDR, MI_WRAM_MAP_NULL ), + MI_WRAM_IMAGE_128KB, + REG_WRAM_MAP_CONV_ADDR( 6, A, SADDR, MI_WRAM_MAP_NULL ) + ), + REG_MI_MBK7_FIELD( REG_WRAM_MAP_CONV_ADDR( 7, B, EADDR, HW_WRAM_AREA_HALF + 0x00080000 ), + MI_WRAM_IMAGE_128KB, + REG_WRAM_MAP_CONV_ADDR( 7, B, SADDR, HW_WRAM_AREA_HALF + 0x00040000 ) + ), + REG_MI_MBK8_FIELD( REG_WRAM_MAP_CONV_ADDR( 8, C, EADDR, HW_WRAM_AREA_HALF + 0x00040000 ), + MI_WRAM_IMAGE_128KB, + REG_WRAM_MAP_CONV_ADDR( 8, C, SADDR, HW_WRAM_AREA_HALF ) + ), + + // ARM7 + REG_MI_MBK6_FIELD( REG_WRAM_MAP_CONV_ADDR( 6, A, EADDR, HW_WRAM_AREA_HALF + 0x00040000 ), + MI_WRAM_IMAGE_128KB, + REG_WRAM_MAP_CONV_ADDR( 6, A, SADDR, HW_WRAM_AREA_HALF ) + ), + REG_MI_MBK7_FIELD( REG_WRAM_MAP_CONV_ADDR( 7, B, EADDR, HW_WRAM_AREA_HALF + 0x00080000 ), + MI_WRAM_IMAGE_128KB, + REG_WRAM_MAP_CONV_ADDR( 7, B, SADDR, HW_WRAM_AREA_HALF + 0x00040000 ) + ), + REG_MI_MBK8_FIELD( REG_WRAM_MAP_CONV_ADDR( 8, C, EADDR, MI_WRAM_MAP_NULL ), + MI_WRAM_IMAGE_128KB, + REG_WRAM_MAP_CONV_ADDR( 8, C, SADDR, MI_WRAM_MAP_NULL ) + ), + + // WRAM Lock + { + 0, + 0, + 0, + }, + + // WRAM-0/1 + 3, + + // VRAM-C + 7, + // VRAM-D + 7, +}; + diff --git a/build/norfirm/norfirm-print/Makefile b/build/norfirm/norfirm-print/Makefile index d5450fd5..b820b2a8 100644 --- a/build/norfirm/norfirm-print/Makefile +++ b/build/norfirm/norfirm-print/Makefile @@ -17,7 +17,7 @@ #---------------------------------------------------------------------------- -FIRM_TARGET = NORFIRM +FIRM_TARGET = FIRM include $(TWLFIRM_ROOT)/build/buildtools/commondefs diff --git a/build/norfirm/norfirm-print/norfirm-BB.norsf b/build/norfirm/norfirm-print/norfirm-BB.norsf index 8b50ee2b..89ceb8d7 100644 --- a/build/norfirm/norfirm-print/norfirm-BB.norsf +++ b/build/norfirm/norfirm-print/norfirm-BB.norsf @@ -12,11 +12,11 @@ WRAM_RBIN: ./wram_regs/wram_regs.rbin DECOMP_PROC : ARM9 # ARM9 or ARM7 ARM9_COMP : TRUE # TRUE or FALSE, should be before ARM9_SBIN -ARM9_SBIN : $(MAKEFIRM_ARM9).sbin +ARM9_SBIN : $(MAKEFIRM_ARM9).FLX.TWL.sbin ARM9_ELF : $(MAKEFIRM_ARM9).axf ARM7_COMP : TRUE # TRUE or FALSE, should be before ARM7_SBIN -ARM7_SBIN : $(MAKEFIRM_ARM7).sbin +ARM7_SBIN : $(MAKEFIRM_ARM7).FLX.TWL.sbin ARM7_ELF : $(MAKEFIRM_ARM7).axf NCD_ROMOFS : 0x07fe00 diff --git a/include/firm.h b/include/firm.h index 8426f838..61d627f2 100644 --- a/include/firm.h +++ b/include/firm.h @@ -20,11 +20,13 @@ #include #include +#include #include +#include +#include /* #include #include -#include #include */ diff --git a/include/firm/aes.h b/include/firm/aes.h index 2a49e8b9..817d8d59 100644 --- a/include/firm/aes.h +++ b/include/firm/aes.h @@ -18,10 +18,9 @@ #define FIRM_AES_H_ #ifdef SDK_ARM7 +#include #include #include -#include -#include #endif // SDK_ARM7 /* FIRM_AES_H_ */ diff --git a/include/firm/aes/ARM7/aes_init.h b/include/firm/aes/ARM7/aes_init.h index 20ab9ef0..00150c7c 100644 --- a/include/firm/aes/ARM7/aes_init.h +++ b/include/firm/aes/ARM7/aes_init.h @@ -1,5 +1,5 @@ /*---------------------------------------------------------------------------* - Project: TwlFirm - AES - include + Project: TwlIPL - AES - include File: aes_init.h Copyright 2007 Nintendo. All rights reserved. @@ -22,14 +22,14 @@ extern "C" { #endif -#ifdef __cplusplus -} /* extern "C" */ -#endif - /*---------------------------------------------------------------------------* 関数定義 *---------------------------------------------------------------------------*/ void AESi_InitGameKeys( u8 game_code[4] ); +#ifdef __cplusplus +} /* extern "C" */ +#endif + /* TWL_AES_AES_INIT_H_ */ #endif diff --git a/include/firm/devices/firm_sdmc/ARM7/sdif_ip.h b/include/firm/devices/firm_sdmc/ARM7/sdif_ip.h new file mode 100644 index 00000000..83e2a67a --- /dev/null +++ b/include/firm/devices/firm_sdmc/ARM7/sdif_ip.h @@ -0,0 +1,349 @@ +/* +** Copyright (c) 2000-2001 Matsushita Electric Industrial Co., Ltd. +** All Rights Reserved. +*/ + +/* +** $Module SDカードアクセスモジュール・インクルード +** $Filename SD_CARD_IP.H +** $Version 1.0 版 +** $Date 01/02/16 +** $Log 01/02/16 rev1.0作成 +** 松下電器産業(株)半導体開発本部 +*/ + + +#ifndef __SD_CARD_IP_H__ +#define __SD_CARD_IP_H__ + +//#define IO3 0 /* Insert Remove SW = FALSE IO3 = TRUE */ + +//#define MAX_SD_CLOCK_4M 0 /* MAX SD Clock 4.608MHz */ +//#define MAX_SD_CLOCK_9M 1 /* MAX SD Clock 9.216MHz */ + + +/*--------------------------------------------- + ラッパーレジスタのビット制御(フラグ定義) +---------------------------------------------*/ +/* SD_CNTレジスタ */ +#define SDIF_CNT_USEDTC (0x0001) /* DTC使用フラグ (R/W) */ +#define SDIF_CNT_USEFIFO (0x0002) /* FIFO使用フラグ (R/W) */ +#define SDIF_CNT_FULL (0x0100) /* FIFO FULLフラグ (RO) */ +#define SDIF_CNT_NEMP (0x0200) /* FIFO NOT EMPTYフラグ (RO) */ +#define SDIF_CNT_FCLR (0x0400) /* FIFO クリアフラグ (WO) */ +#define SDIF_CNT_FFIE (0x0800) /* FIFO FULLで割り込み (R/W) */ +#define SDIF_CNT_FEIE (0x1000) /* FIFO EMPTYで割り込み (R/W) */ + +#define SDCARD_UseFifoFlag ((*SDIF_CNT) & SDIF_CNT_USEFIFO) + +/*------------------------------------- +レジスタのビット制御(フラグ定義) +-------------------------------------*/ +/* SD_CMDレジスタ*/ +#define SD_CMD_CMD 0x0000 /* SDカードへの通常アクセス(CMD) */ +#define SD_CMD_ACMD 0x0040 /* SDカードへのセキュリティアクセス(ACMD) */ + +/* SD_STOPレジスタ */ +#define SD_STOP_STP 0x0001 /* データ転送終了を知らせる */ +#define SD_STOP_SEC_ENABLE 0x0100 /* SD_SECCNTレジスタ有効(セクタカウントレジスタ) */ + +/* SD_SECCNTレジスタ */ +#define SD_SECCNT_END 0x0000 /* SD_SECCNTレジスタ カウントチェック */ + +/* SD_SIZEレジスタ */ +#define SD_SIZE_DATA_LENGTH_1B 0x0001 /* SDカード転送データサイズ 1Bytes */ +#define SD_SIZE_DATA_LENGTH_2B 0x0002 /* SDカード転送データサイズ 2Bytes */ +#define SD_SIZE_DATA_LENGTH_4B 0x0004 /* SDカード転送データサイズ 4Bytes */ +#define SD_SIZE_DATA_LENGTH_8B 0x0008 /* SDカード転送データサイズ 8Bytes (SCR) */ +#define SD_SIZE_DATA_LENGTH_16B 0x0010 /* SDカード転送データサイズ 16Bytes */ +#define SD_SIZE_DATA_LENGTH_32B 0x0020 /* SDカード転送データサイズ 32Bytes */ +#define SD_SIZE_DATA_LENGTH_64B 0x0040 /* SDカード転送データサイズ 64Bytes (SD_Status) */ +#define SD_SIZE_DATA_LENGTH_128B 0x0080 /* SDカード転送データサイズ 128Bytes */ +#define SD_SIZE_DATA_LENGTH_256B 0x0100 /* SDカード転送データサイズ 256Bytes */ +#define SD_SIZE_DATA_LENGTH_512B 0x0200 /* SDカード転送データサイズ 512Bytes (データ) */ + +/* SD_OPTIONレジスタ */ +#define SD_OPTION_WIDTH_1BIT 0x8000 /* ビット幅の選択 1bit幅 */ +#define SD_OPTION_MSEL_C2NOUSE 0x4000 /* C2モジュール未使用 */ +#define SD_CD_DETECT_TIME 0xFFF0 /* CD 検出タイムだけをクリアするためのマスク */ + +/* SD_INFO2レジスタ */ +#define SD_INFO2_ERR_ILA 0x8000 /* イリーガルアクセスエラー */ +#define SD_INFO2_BWE 0x0200 /* SDカードから512byteのデータ書込み要求 */ +#define SD_INFO2_BRE 0x0100 /* SDカードから512byteのデータ読込み要求 */ +#define SD_INFO2_ERR_ALLCLR 0x807F /* SD Card エラーレジスタクリア */ +#define SD_INFO2_ERR_SDDAT0 0x0080 /* SD Card Busy bit */ +#define SD_INFO2_ERR_RESTIMEOUT 0x0040 /* レスポンスタイムアウトエラー */ +#define SD_INFO2_ERR_UNDERFLOW 0x0020 /* FIFO アンダーフローエラー */ +#define SD_INFO2_ERR_OVERFLOW 0x0010 /* FIFO オーバーフローエラー */ +#define SD_INFO2_ERR_TIMEOUT 0x0008 /* レスポンス以外のタイムアウトエラー */ +#define SD_INFO2_ERR_END 0x0004 /* フレーム終了認識できないときの(END)エラー */ +#define SD_INFO2_ERR_CRC 0x0002 /* CRC エラー */ +#define SD_INFO2_ERR_CMD 0x0001 /* CMDエラー */ + +#define SD_INFO2_RW_SET 0x0300 /* SDカード Read/Write 要求割込み要因チェック */ +#define SD_INFO2_ERROR_SET 0x807F /* SDカード エラー割込み要因チェック */ + +/* SD_INFO2_MASKレジスタ */ +#define SD_INFO2_MASK_ILA 0x8000 /* イリーガルアクセスエラー割込みマスク */ +#define SD_INFO2_MASK_BWE 0x0200 /* SDカードからのデータ書込み要求割込み禁止 */ +#define SD_INFO2_MASK_BRE 0x0100 /* SDカードからのデータ読込み要求割込み禁止 */ +#define SD_INFO2_MASK_ALLERRMASK 0x807F /* 全エラー割り込み禁止 */ +#define SD_INFO2_MASK_EXCEPT_OVERFLOW 0x802F /* 全エラー割り込み禁止 FIFO Overflow Errorを除く */ +#define SD_INFO2_MASK_RESTIMEOUT 0x0040 /* Time out 割込みEnable */ +#define SD_INFO2_MASK_UNDERFLOW 0x0020 /* FIFO アンダーフロー 割込みEnable */ +#define SD_INFO2_MASK_OVERFLOW 0x0010 /* FIFO オーバーフロー 割込みEnable */ +#define SD_INFO2_MASK_TIMEOUT 0x0008 /* Time out 割込みEnable */ +#define SD_INFO2_MASK_END 0x0004 /* END エラー 割込みEnable */ +#define SD_INFO2_MASK_CRC 0x0002 /* CRC エラー 割込みEnable */ +#define SD_INFO2_MASK_CMD 0x0001 /* CMD エラー 割込みEnable */ +#define SD_INFO2_MASK_ERRSET 0x807F /* SDカード エラー割込み要因チェック */ + +/* SD_INFO1レジスタ */ +#define SD_INFO1_DAT3DETECT 0x0400 /* (IO3検出) card detect(検出=1) : CTRでは使用できない*/ +#define SD_INFO1_DAT3INSERT 0x0200 /* (IO3検出) card inserted(挿入=1) : CTRでは使用できない */ +#define SD_INFO1_DAT3REMOVE 0x0100 /* (IO3検出) card removed(抜け=1) : CTRでは使用できない */ +#define SD_INFO1_DAT3INIT 0x0300 /* (IO3検出) の初期化 */ +#define SD_INFO1_WRITEPROTECT 0x0080 /* write protect(書き込み禁止=1) */ +#define SD_INFO1_DETECT 0x0020 /* card detect(検出=1) */ + +#define SD_INFO1_INSERT 0x0010 /* card inserted(挿入=1) */ +#define SD_INFO1_REMOVE 0x0008 /* card removed(抜け=1) */ + +#define SD_INFO1_ALL_END 0x0004 /* R/W access all end */ +#define SD_INFO1_RES_END 0x0001 /* Response end */ +#define SD_INFO1_INIT 0x0005 /* SD Cardの状態を初期化 */ + +#define SD_INFO1_SET 0x031D /* SDカード 挿抜 and RWアクセス終了 and レスポンス終了 要求割込み要因チェック */ + +/* SD_INFO1_MASKレジスタ (0:割り込み許可、1:割り込み禁止)*/ +#define SD_INFO1_MASK_DAT3INSERT 0x0200 /* (IO3検出) card inserted(挿入) 割込み禁止 */ +#define SD_INFO1_MASK_DAT3REMOVE 0x0100 /* (IO3検出) card removed(抜け) 割込み禁止 */ +#define SD_INFO1_MASK_INSERT 0x0010 /* card inserted(挿入) 割込み禁止 */ +#define SD_INFO1_MASK_REMOVE 0x0008 /* card removed(抜け) 割込み禁止 */ +#define SD_INFO1_MASK_ALL_END 0x0004 /* R/W access all end 割込み禁止 */ +#define SD_INFO1_MASK_RES_END 0x0001 /* Response end 割込み禁止 */ + +/* CC_EXT_MODEレジスタ */ +#define CC_EXT_MODE_PIO 0x0000 /* PIOモード */ +#define CC_EXT_MODE_DMA 0x0002 /* DMAモード */ + +/* SOFT_RSTレジスタ */ +#define SOFT_RST_SDIF_RST 0x0001 /* SD I/Fモジュールをリセット */ + +/* SD_CLK_CTRLレジスタ */ +#define SD_CLK_CTRL_SDCLKEN 0x0100 /* SDカードクロック出力イネーブル */ +#define SD_CLK_CTRL_512 0x0180 /* SDクロックの周波数(分周比512)*/ +#define SD_CLK_CTRL_256 0x0140 /* SDクロックの周波数(分周比256)*/ +#define SD_CLK_CTRL_128 0x0120 /* SDクロックの周波数(分周比128)*/ +#define SD_CLK_CTRL_64 0x0110 /* SDクロックの周波数(分周比 64)*/ +#define SD_CLK_CTRL_32 0x0108 /* SDクロックの周波数(分周比 32)*/ +#define SD_CLK_CTRL_16 0x0104 /* SDクロックの周波数(分周比 16)*/ +#define SD_CLK_CTRL_8 0x0102 /* SDクロックの周波数(分周比 8)*/ +#define SD_CLK_CTRL_4 0x0101 /* SDクロックの周波数(分周比 4)*/ +#define SD_CLK_CTRL_2 0x0100 /* SDクロックの周波数(分周比 2)*/ + + +/*------------------------------------- +マルチポート対応ビット制御(フラグ定義) +-------------------------------------*/ +#define SDCARD_PORT_NO 0x0300 /* カードポート選択数 */ +#define SDCARD_PORT_NO_MAX 0x04//0x02 /* カードポート最大選択数 */ +#define SDCARD_PORT_NO_MIN 0x01 /* カードポート最小選択数 */ +#define SDCARD_PORT_SELECT_NO 0x0001 /* カードポート番号ビット */ +#define SDCARD_PORT0 0x0000 /* カードポート番号ビット */ +#define SDCARD_PORT1 0x0001 /* カードポート番号ビット */ + +/* EXT_WPレジスタ(ポート1以降のライトプロテクト) */ +#define EXT_WP_PORT1 0x0001 /* ポート1write protect(書き込み禁止=1)*/ + +/* EXT_CDレジスタ */ +#define EXT_CD_PORT1_REMOVE 0x0001 /* ポート1 card detect(検出=1) */ +#define EXT_CD_PORT1_INSERT 0x0002 /* ポート1 card inserted(挿入=1) */ +#define EXT_CD_PORT1_DETECT 0x0004 /* ポート1 card removed(抜け=1) */ + +/* EXT_CD_DAT3レジスタ */ +//#define EXT_CD_PORT1_DAT3INIT 0x0003 /* ポート1 card の状態 (IO3検出) の初期化 */ +#define EXT_CD_PORT1_DAT3REMOVE 0x0001 /* ポート1 dat3 card detect(検出=1) */ +#define EXT_CD_PORT1_DAT3INSERT 0x0002 /* ポート1 dat3 card inserted(挿入=1) */ +#define EXT_CD_PORT1_DAT3DETECT 0x0004 /* ポート1 dat3 card removed(抜け=1) */ + +/* EXT_CD_DAT3_MASKレジスタ */ +#define EXT_CD_MASK_PORT1INSERT 0x0002 /* port1 card inserted(挿入) 割込み禁止 */ +#define EXT_CD_MASK_PORT1REMOVE 0x0001 /* port1 card removed(抜け) 割込み禁止 */ +#define EXT_CD_MASK_PORT1DAT3INSERT 0x0002 /* port1 (IO3検出) card inserted(挿入) 割込み禁止 */ +#define EXT_CD_MASK_PORT1DAT3REMOVE 0x0001 /* port1 (IO3検出) card removed(抜け) 割込み禁止 */ + +/*------------------------------------- +カードの選択 +--------------------------------------*/ +#define SDCARD_DETECT_VISUAL_BIT 0x0400 /*** upper layer card detected visual bit ***/ + +/*------------------------------------- +ライトプロテクト +-------------------------------------*/ +#define SDCARD_WP_PERMANENT_BIT 0x0020 /*** permanent write protection ***/ +#define SDCARD_WP_TEMPORARY_BIT 0x0010 /*** temporary write protection ***/ + +/*------------------------------------- +SD or MMCカードコマンド +-------------------------------------*/ +#define GO_IDLE_STATE (0) /* resets all cards to idle state */ +#define SEND_OP_COND (1) /* Asks all cards in idle state to send their operation conditions */ +#define ALL_SEND_CID (2) /* send CID numbers */ +#define SEND_RELATIVE_ADDR (3) /* ask the card to publish a new relative address(RCA) */ +#define SET_BUS_WIDTH (6) /* ビット幅の選択 */ +#define SELECT_CARD (7) /* Command toggles acard between thr Stand-by and Transfer states */ +#define SEND_CSD (9) /* addressed card sends its card-specific data(CSD) */ +#define STOP_TRANSMISSION (12) /* forces the card to stop transmission */ +#define SD_SEND_STATUS (13) /* addressed card sends its status register */ +#define SET_BLOCKLEN (16) /* sets the block length */ +#define READ_MULTIPLE_BLOCK (18) /* マルチブロックリード */ +#define WRITE_MULTIPLE_BLOCK (25) /* マルチブロックライト */ +#define APP_CMD (55) /* CMD55 */ +#define SD_STATUS (13) /* ACMD13 Send the SD_CARD status */ +#define SEND_NUM_WR_SECTORS (22) /* ACMD22 書きこみ完了セクタ数取得 */ +#define SD_APP_OP_COND (41) /* ACMD41 */ +#define SEND_SCR (51) /* SD configuration register (SCR) */ + +/* MMCplus, eMMCの定義 */ +#define EXT_CSD_ACCESS (6) + +/* Extended Commandの定義 */ +#define EXT_NORMAL (0) +#define EXT_SDIO (0x4000) + +#define EXT_COM_R3 (0x0700) + +#define EXT_CMD (0x00C0) + +#define SEND_IF_COND (8) /* Physical Layer 2.0 で追加されたコマンド */ +#define SEND_IF_COND_EXT (EXT_SDIO | EXT_COM_R3 | EXT_CMD | SEND_IF_COND) + + +/*------------------------------------- +IP レジスタアクセス マクロ関数 +-------------------------------------*/ +#define SD_OrFPGA(reg,value) ((reg) |= (value)); +#define SD_AndFPGA(reg,value) ((reg) &= (value)); +#define SD_SetFPGA(reg,value) ((reg) = (value)); +#define SD_GetFPGA(dest,reg) ((dest) = (reg)); + +/*********************************************************************** + 構造体定数 +***********************************************************************/ +typedef union{ + u32 dat; + struct { + u16 low; + u16 high; + } dt2word; +} LELONG; + +/*------------------------------------- +その他(ビット制御) +-------------------------------------*/ +#define RSP_R3_OCR31 0x8000 /* Use OCR Busy bit Check */ +#define RSP_R3_OCR_VDD 0x0030 /* Use OCR VDD bit Check (3.2-3.3v,3.3-3.4v is OK)*/ + +/*--- SCR[0]に対する4bitバス幅対応フラグのマスク ---*/ +//SCRのbit50に相当するが、SCRとSD_STATUSはMSBから送られてくることを考慮してある +#define SCR_DAT_BUS_WIDTH_4BIT 0x0400 /* SCR DAT Bus width supported 4bit */ + +/*--- 127bitCSD (CSD[0]〜CSD[7])関連 ---*/ +#define CSD_VDD_R_CURR_MIN 0x0038 /* "VDD_R_CURR_MIN" (for CSD[3]) */ +#define CSD_VDD_R_CURR_MAX 0x0007 /* "VDD_R_CURR_MAX" (for CSD[3]) */ +#define CSD_VDD_W_CURR_MIN 0xE000 /* "VDD_W_CURR_MIN" (for CSD[2]) */ +#define CSD_VDD_W_CURR_MAX 0x1C00 /* "VDD_W_CURR_MAX" (for CSD[2]) */ + +#define CSD_READ_BL_LEN 0x0F00 /* "READ_BL_LEN" (for CSD[4])*/ +#define CSD_WRITE_BL_LEN_BIT_25_24 0x0003 /* "WRITE_BL_LEN" (for CSD[1])*/ +#define CSD_WRITE_BL_LEN_BIT_23_22 0xC000 /* "WRITE_BL_LEN" (for CSD[0]*/ +#define CSD_READ_BL_PARTIAL 0x0080 /* "READ_BL_PARTIAL" (for CSD[4]) */ +#define CSD_TRANSFER_RATE 0x0700 /* "Transfer rate unit" of "TRAN_SPEED" (for CSD[5]) */ +#define CSD_TRAN_SPEED_100K 0x0000 /* 100Kbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_1M 0x0001 /* 1Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_10M 0x0002 /* 10Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_100M 0x0003 /* 100Mbit/s (for CSD Transfer rate) */ +#define CSD_TRAN_SPEED_OTHER 0x0004 /* Reserve (for CSD Transfer rate) */ + +#define CSD_C_SIZE_MULT 0x0380 /* RSP2 の bit[49:47] */ +#define CSD_C_SIZE_BIT_73_72 0x0003 /* RSP3 の bit[73:72](C_SIZE) */ +#define CSD_C_SIZE_BIT_71_62 0xFFC0 /* RSP3 の bit[71:62](C_SIZE) */ +//SDHC(CSD format version2)の場合 +#define CSD_C_SIZE_BIT_69_56 0x3FFF /* SD_CSD[3] */ +#define CSD_C_SIZE_BIT_55_48 0xFF00 /* SD_CSD[2] */ + +#define CSD_STRUCT_BIT_127_126 0x00C0 /* SD_CSD[7] */ + +//#define VDD_R_CURR_MIN 0x0000 /* CSD max read current@VDD min */ +//#define VDD_R_CURR_MAX 0x0007 /* CSD max read current@VDD max */ +//#define VDD_W_CURR_MIN 0x0000 /* CSD max write current@VDD min */ +//#define VDD_W_CURR_MAX 0x0007 /* CSD max write current@VDD max */ + +/*--- R1レスポンスの card status(32bit)に対するマスク ---*/ +#define RSP_R1_STATUS_ERR 0xF9FF0008 /* R1(レスポンス)のカードステータスのチェック */ +#define SDCARD_STATUS_OUT_OF_RANGE 0x80000000 /* Card Status OUT_OF_RANGE のチェック */ +#define RSP_R1_CURRENT_STATE 0x1E00 /* CARD current state */ +/*-------------------------------------------------------*/ + +/* レスポンスのRSP0 & RSP_R1_CURRENT_STATEを1ビット右シフトした値に対するフラグ */ +#define CURRENT_STATE_DATA 0x0500 /* CARD current state data */ +#define CURRENT_STATE_RCV 0x0600 /* CARD current state rcv */ + +/* カードステータス */ +#define SD_MEMORY_CARD 0x00FF /* SD_CARD_TYPE SD memory card */ + + +/*------------------------------------- +プロトタイプ宣言 +-------------------------------------*/ +void SD_Init(void); /* SD Cardインターフェース部をリセット&初期設定 */ +void SD_EnableInfo(void); /* SD Card 挿抜 割り込みイネーブル・ディスエーブル */ +u16 SD_Command(u16 ucCommand); /* SDカードコマンド送出 */ +u16 SD_AppCommand(void); /* SDカード RCA = 1をセット後 CMD55 発行 */ +u16 SD_AppOpCond(void); /* ACMD41 発行 busyでなくなるまで繰り返し */ +u16 SD_SendOpCond(void); /* CMD1 発行 busyでなくなるまで繰り返し */ +u16 SD_SendIfCond(void); /* CMD8 発行 (SDHCのみ反応してくる) */ +u16 SD_SendRelativeAddr(void); /* CMD3 発行 正常終了時 RCA<-ResのRCA */ +u16 SD_SelectCard(void); /* CMD7 発行 Command toggles acard between the Stand-by and Transfer states */ +u16 SD_SetBlockLength(u32 ulBlockLength); /* ブロックレングス(1セクタの転送量)の設定 */ +u16 SD_SendCID(void); /* card identification data の取得コマンド発行 */ +u16 SD_SendCSD(void); /* card-specific data の取得コマンド発行 */ +u16 SD_SendSCR(void); /* SD register の取得コマンド発行 */ +u16 SD_SDStatus(void); /* SD STATUS の取得コマンド発行 */ +u16 SD_SendStatus(void); /* SD status register の取得コマンド発行 */ +u16 SD_MultiReadBlock(u32 ulOffset); /* マルチセクタリードコマンド発行 */ +u16 SD_ClockDivSet(u16 usTranSpeed); /* カードの動作クロック設定 */ + +void SD_EnableClock( void); /* SDカードのクロック有効 */ +void SD_DisableClock( void); /* SDカードのクロック無効(省電力) */ + +u16 SD_SelectBitWidth(s16 b4bit); /* ビット幅の選択 */ + +u16 MMCP_WriteBusWidth(s16 b4bit); +u16 MMCP_BusTest( BOOL readflag); + + +BOOL SD_FPGA_irq(void); /* カード転送要求時のFPGAの制御 */ +void SD_StopTransmission(void); /* カード転送終了をFPGAに通知する。 */ +void SD_TransEndFPGA(void); /* カード転送の終了処理(割り込みマスクを戻す) */ +u16 SD_CheckStatus(BOOL bRead); /* Normal response command カードステータスのチェック */ +u16 SD_SwapByte(u16 *data); /* 上位byte、下位byteを入れ替える関数 */ + +void SD_EnableSeccnt( u32 ulSDCARD_SectorCount); /* SD_SECCNTレジスタ有効化&値設定 */ +void SD_DisableSeccnt( void); /* SD_SECCNTレジスタ無効化 */ + +void SD_SetErr(u16 Error); /* エラーステータスを設定する */ +void SD_ClrErr(u16 Error); /* エラーステータスをクリアする */ + +BOOL SD_CheckFPGAReg(u16 reg,u16 value); /* IPレジスタにフラグが立っているか判定 */ + +void SD_TransReadyFPGA(void); /* 転送処理準備FPGA設定 */ +u16 SD_TransCommand(u16 ucCommand); /* 命令発行処理 */ + +u16 SD_MultiWriteBlock(u32 ulOffset); /* マルチセクタライトコマンド発行 */ +u16 SD_SendNumWRSectors(void); /* ACMD22 書きこみ完了セクタ数取得コマンド発行 */ + + +#endif /* __SD_CARD_IP_H__ */ diff --git a/include/firm/devices/firm_sdmc/ARM7/sdif_reg.h b/include/firm/devices/firm_sdmc/ARM7/sdif_reg.h new file mode 100644 index 00000000..a5f4f862 --- /dev/null +++ b/include/firm/devices/firm_sdmc/ARM7/sdif_reg.h @@ -0,0 +1,118 @@ +/*---------------------------------------------------------------------------* + Project: TwlBrom - SD driver + File: sd_ip_reg.h + + Copyright 2006 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. + *---------------------------------------------------------------------------*/ + +#ifndef __SD_IP_REG_H__ +#define __SD_IP_REG_H__ + +/********************************************* + SD IPレジスタ + + (R/W) : readable and writable + (RO) : read only +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define SD_IP_BASE (0x08030000) // NTR用ブレッドボード設定 +#else +#define SD_IP_BASE (0x400B0000) // IOP実機設定 +#endif*/ +#define SD_IP_BASE (0x04004800) // TWL ARM7設定 + + +#define SD_CMD (*(vu16 *)(SD_IP_BASE + 0x00)) /* CMD発行レジスタ(R/W) */ +#define SD_PORTSEL (*(vu16 *)(SD_IP_BASE + 0x02)) /* ポート選択レジスタ(R/W) */ +#define SD_ARG0 (*(vu16 *)(SD_IP_BASE + 0x04)) /* Argument[15:0] (R/W) */ +#define SD_ARG1 (*(vu16 *)(SD_IP_BASE + 0x06)) /* Argument[31:16] (R/W) */ +#define SD_STOP (*(vu16 *)(SD_IP_BASE + 0x08)) /* 転送終了後STOP、SD_SECCNT有効 (R/W) */ +#define SD_SECCNT (*(vu16 *)(SD_IP_BASE + 0x0A)) /* 転送セクタ数制御 (R/W) */ +#define SD_RSP0 (*(vu16 *)(SD_IP_BASE + 0x0C)) /* Response [23:8] (RO) */ +#define SD_RSP1 (*(vu16 *)(SD_IP_BASE + 0x0E)) /* Response [39:24] (RO) */ +#define SD_RSP2 (*(vu16 *)(SD_IP_BASE + 0x10)) /* Response [55:40] (RO) */ +#define SD_RSP3 (*(vu16 *)(SD_IP_BASE + 0x12)) /* Response [71:56] (RO) */ +#define SD_RSP4 (*(vu16 *)(SD_IP_BASE + 0x14)) /* Response [87:72] (RO) */ +#define SD_RSP5 (*(vu16 *)(SD_IP_BASE + 0x16)) /* Response [103:88] (RO) */ +#define SD_RSP6 (*(vu16 *)(SD_IP_BASE + 0x18)) /* Response [119:104] (RO) */ +#define SD_RSP7 (*(vu16 *)(SD_IP_BASE + 0x1A)) /* Response [127:120] (RO) */ +#define SD_INFO1 (*(vu16 *)(SD_IP_BASE + 0x1C)) /* SDメモリーカードの状態 (R/W) */ +#define SD_INFO2 (*(vu16 *)(SD_IP_BASE + 0x1E)) /* バッファ制御とエラー情報 (R/W) */ +#define SD_INFO1_MASK (*(vu16 *)(SD_IP_BASE + 0x20)) /* SD_INFO1割込みマスク (R/W) */ +#define SD_INFO2_MASK (*(vu16 *)(SD_IP_BASE + 0x22)) /* SD_INFO2割込みマスク (R/W) */ +#define SD_CLK_CTRL (*(vu16 *)(SD_IP_BASE + 0x24)) /* SDクロック設定 (R/W) */ +#define SD_SIZE (*(vu16 *)(SD_IP_BASE + 0x26)) /* ビット幅と転送データ長の設定 (R/W) */ +#define SD_OPTION (*(vu16 *)(SD_IP_BASE + 0x28)) /* タイムアウト、width、CD検出タイム (R/W) */ +#define SD_ERR_STS1 (*(vu16 *)(SD_IP_BASE + 0x2C)) /* CMD, CRC, ENDエラー割込み原因 (RO) */ +#define SD_ERR_STS2 (*(vu16 *)(SD_IP_BASE + 0x2E)) /* タイムアウトエラー割込み原因 (RO) */ +#define SD_BUF0 (vu16 *)(SD_IP_BASE + 0x30) /* SDバッファ読込/書込データポート (R/W) */ +#define CC_EXT_MODE (*(vu16 *)(SD_IP_BASE + 0xD8)) /* DMAモード/PIOモード切り替え */ +#define SOFT_RST (*(vu16 *)(SD_IP_BASE + 0xE0)) /* ソフトウェアリセット (R/W) */ +#define VERSION (*(vu16 *)(SD_IP_BASE + 0xE2)) /* Version レジスタ (RO) */ +#define EXT_WP (*(vu16 *)(SD_IP_BASE + 0xF6)) /* 拡張SD Card ライトプロテクト (RO) */ +#define EXT_CD (*(vu16 *)(SD_IP_BASE + 0xF8)) /* 拡張SD Card 検出、挿入、抜け フラグ (R/W) */ +#define EXT_CD_DAT3 (*(vu16 *)(SD_IP_BASE + 0xFA)) /* 拡張SD Card 検出、挿入、抜け フラグ (R/W) */ +#define EXT_CD_MASK (*(vu16 *)(SD_IP_BASE + 0xFC)) /* 拡張SD Card 検出、挿入、抜け 割込みマスク (R/W) */ +#define EXT_CD_DAT3_MASK (*(vu16 *)(SD_IP_BASE + 0xFE)) /* 拡張SD Card 検出、挿入、抜け 割込みマスク (R/W) */ + + + +/********************************************* + SD I/F(ラッパー)レジスタ +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define SD_IF_BASE (0x08030100) // NTR用ブレッドボード設定 +#else +#define SD_IF_BASE (0x400B0100) // IOP実機設定 +#endif*/ +#define SD_IF_BASE (0x04004900) // IOP実機設定 + + +#define SDIF_CNT ((vu32 *)(SD_IF_BASE+0x00)) /* コントロール */ +#define SDIF_FDS ((vu32 *)(SD_IF_BASE+0x04)) /* FIFOサイズ */ +#define SDIF_FSC ((vu32 *)(SD_IF_BASE+0x08)) /* セクタカウント */ +#define SDIF_FI ((vu32 *)(SD_IF_BASE+0x0c)) /* FIFOウィンドウ */ + +#define SDIF_CNT_L ((vu16 *)(SD_IF_BASE+0x00)) +#define SDIF_CNT_H ((vu16 *)(SD_IF_BASE+0x02)) +#define SDIF_FDS_L ((vu16 *)(SD_IF_BASE+0x04)) +#define SDIF_FDS_H ((vu16 *)(SD_IF_BASE+0x06)) +#define SDIF_FSC_L ((vu16 *)(SD_IF_BASE+0x08)) +#define SDIF_FSC_H ((vu16 *)(SD_IF_BASE+0x0a)) +#define SDIF_FI_L ((vu16 *)(SD_IF_BASE+0x0c)) +#define SDIF_FI_H ((vu16 *)(SD_IF_BASE+0x0e)) + + + +/********************************************* + INTCレジスタ +*********************************************/ +/*#if (CTR_DEF_ENVIRONMENT_DSEMU == 1) +#define CTR_INT_BASE (0x08000000) +#else +#define CTR_INT_BASE (0x40010000) +#endif + + +#define CTR_INT_SE (CTR_INT_BASE + 0x00) //割り込み要求選択レジスタ +#define CTR_INT_IE (CTR_INT_BASE + 0x04) //IE +#define CTR_INT_IF (CTR_INT_BASE + 0x08) //IF + +#define CTR_IE_SD_MASK (1<<13) //SD割り込みフラグ +*/ +#define CTR_INT_BASE (0x04000000) + +#define CTR_INT_SE (CTR_INT_BASE + 0x208) //割り込み要求選択レジスタ +#define CTR_INT_IE (CTR_INT_BASE + 0x218) //IE +#define CTR_INT_IF (CTR_INT_BASE + 0x21C) //IF + +#define CTR_IE_SD_MASK (1<<8) //SD割り込みフラグ + + +#endif /* __SD_IP_REG_H__ */ diff --git a/include/firm/devices/firm_sdmc/ARM7/sdmc_config.h b/include/firm/devices/firm_sdmc/ARM7/sdmc_config.h new file mode 100644 index 00000000..7c645077 --- /dev/null +++ b/include/firm/devices/firm_sdmc/ARM7/sdmc_config.h @@ -0,0 +1,87 @@ +/* +** Copyright (c) 2000-2001 Matsushita Electric Industrial Co., Ltd. +** All Rights Reserved. +*/ + +/* +** $System IP1.1 without C2 サンプルソフト +** $Subsystem カードドライバ +** $Filename CARDDRV.H +** $Version 1.0 版 +** $Date 01/02/16 +** $Log 01/02/16 rev1.0作成 +** 松下電器産業(株)半導体開発本部 +*/ + + +#ifndef __SDMC_CONFIG_H__ +#define __SDMC_CONFIG_H__ + + +#include + +#ifdef USE_OS +#include /* IP 対応レジスタ定義 */ +#endif + + + +/********************************************* + ターゲットOS +*********************************************/ +#define TARGET_OS_CTR (0) +#define TARGET_OS_NITRO (TARGET_OS_CTR ^ 1) + + +/********************************************* + SDドライバ コンフィグレーション +*********************************************/ +#define SD_DEBUG_PRINT_ON 0 /* デバッグ表示 */ + +#define WP_ena 1 /* ライトプロテクトのチェック有効 */ +#define TIMEOUT 1 /* FPGA Timeout none = FALSE */ +#define SCR 1 /* Send SCR Command = TRUE */ +#define RESID 1 /* Write Error Resid enable = TRUE */ +#define ATC_ON 0 /* ATC転送 使用/未使用 */ + +#define SecEnable 1 /* SD_SECCNTレジスタ Enable */ +#define SecDisenable 0 /* SD_SECCNTレジスタ Disable */ +//#define STANDBYMODE 0x04 /*** 5772 standby control bit ***/ + +#define SDCARD_TIMER_ID (OS_TIMER_3) + + +/********************************************* + タイムアウト設定値(ms単位) +*********************************************/ +#define SDCARD_RW_TIMEOUT (2000) +#define SDCARD_STDBY_TIMEOUT (50) +#define SDCARD_CLOCK_WAIT (500) +#define SDCARD_SDCLK_WAIT (10) +#define SDCARD_INITIAL_TIMEOUT (800) +#define SDCARD_RESET_TIMEOUT (1500) +#define SDCARD_ERASE_TIMEOUT (1) +#define SDCARD_ERRPROC_TIMEOUT (2000) + + +/********************************************* + リトライ回数(Multiple Block R/W のとき) +*********************************************/ +#define SDCARD_RETRY_COUNT (3) + +/********************************************* + その他 +*********************************************/ +#define SECTOR_SIZE (512) /* 1セクタのバイト数 */ +#define SECTOR_MAX (255) /* SYSFPGA アクセス最大セクタ数 */ + +/*--- 上位レイヤに返すステータス値(SDCARD_Getstatus参照)用 ---*/ +#define SDCARD_FLAG_CLR (0x3FFF) /* カード判定部分クリア用 */ +#define SDCARD_FLAG_SD (0x8000) /* カード判定部分SDカード */ +#define SDCARD_FLAG_MMC (0x4000) /* カード判定部分MMCカード */ +#define SDCARD_PORT1_CLR (0x0007) /* カードポート1判定部分クリア用 */ + + + + +#endif /*__SDMC_CONFIG_H__*/ diff --git a/include/firm/devices/firm_sdmc/ARM7/sdmc_types.h b/include/firm/devices/firm_sdmc/ARM7/sdmc_types.h new file mode 100644 index 00000000..457c4494 --- /dev/null +++ b/include/firm/devices/firm_sdmc/ARM7/sdmc_types.h @@ -0,0 +1,127 @@ + +#ifndef __SDMC_TYPES_H__ +#define __SDMC_TYPES_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/********************************************* + ポート番号 +*********************************************/ +typedef enum { + SDMC_PORT_CARD = 0x400, + SDMC_PORT_NAND = 0x401 +}SDMC_PORT_NO; + + +/********************************************* + DMA番号 +*********************************************/ +typedef enum { + SDMC_USE_DMA_0 = 0, + SDMC_USE_DMA_1 = 1, + SDMC_USE_DMA_2 = 2, + SDMC_USE_DMA_3 = 3, + SDMC_NOUSE_DMA = 0xFF +}SDMC_DMA_NO; + + +/********************************************* + カードエラーコード(カードエラーステータス設定値)アプリケーション固有のSDCARD_ErrStatusに対して +*********************************************/ +typedef enum { + SDMC_NORMAL = 0, /* 正常終了 */ + SDMC_ERR_COMMAND = 0x0001, /* CMDエラー */ + SDMC_ERR_CRC = 0x0002, /* CRCエラー */ + SDMC_ERR_END = 0x0004, /* 実行エラー */ + SDMC_ERR_TIMEOUT = 0x0008, /* コマンドタイムアウト */ + SDMC_ERR_FIFO_OVF = 0x0010, /* FIFO オーバーフローエラー(INFO2のIllegal write access to buffer) */ + SDMC_ERR_FIFO_UDF = 0x0020, /* FIFO アンダーフローエラー(INFO2のIllegal read access to buffer) */ + SDMC_ERR_WP = 0x0040, /* WriteProtectによる書き込みエラー */ + SDMC_ERR_FPGA_TIMEOUT = 0x0100, /* FPGA アクセスタイムアウト */ + SDMC_ERR_PARAM = 0x0200, /* コマンドパラメータエラー */ + SDMC_ERR_R1_STATUS = 0x0800, /* Normal response command カードステータス エラー */ + SDMC_ERR_NUM_WR_SECTORS = 0x1000, /* 書き込み完了セクタ数 エラー */ + SDMC_ERR_RESET = 0x2000, /* 初期化カードリセットコマンド時1.5秒タイムアウトエラー */ + SDMC_ERR_ILA = 0x4000, /* イリーガルアクセスエラー */ + SDMC_ERR_INFO_DETECT = 0x8000 /* カード排出時判別エラービット(IO3) */ +}SDMC_ERR_CODE; + + +/********************************************* + SDドライバ処理結果通知情報構造体 +*********************************************/ +typedef struct { + u16 b_flags; /* 処理内容 */ + u16 result; /* 実行結果 */ + u32 resid; /* 読み(書き)サイズ */ +} SdmcResultInfo; + + + + + +/********************************************* + SDポート状態保存用構造体 +*********************************************/ +typedef struct +{ + 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 MMCFlag; + s16 SDHCFlag; + s16 SDFlag; + SDMC_ERR_CODE ErrStatus; /* SDCARD_ErrStatus */ + u32 Status; /* SDCARD_Status */ + u16 SD_CLK_CTRL_VALUE; + u16 SD_OPTION_VALUE; + + s16 OutFlag; + u16 port_no; +} +SDPortContext; + + + + + +/********************************************* + SDスペック構造体 +*********************************************/ +typedef struct { + u32 csd_ver2_flag; //CSDフォーマットバージョン(SDHCのときは1) + u32 memory_capacity; //data areaのサイズ(512Byte単位) + u32 protected_capacity; //protected areaのサイズ(512Byte単位) + u32 card_capacity; //カード全体のサイズ(512Byte単位) + + u32 adjusted_memory_capacity; //memory_capacityをシリンダ(heads*secptrack)の倍数に調整したサイズ(cylinders*heads*secptrackになる) + + u16 heads; + u16 secptrack; + u16 cylinders; + u16 SC; //sectors per cluster + u16 BU; + u16 RDE; //number of root dir entries(512 fix) + u32 SS; //sector size(512 fix) + u32 RSC; //reserved sector count(1 fix) +// u32 TS; //total sectors + u16 FATBITS; //16 or 32 + u16 SF; //sectors per FAT + u32 SSA; //sectors in system area + u32 NOM; //sectors in master boot record +} SdmcSpec; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /*__SDMC_TYPES_H__*/ diff --git a/include/firm/fatfs.h b/include/firm/fatfs.h new file mode 100644 index 00000000..2d6cc208 --- /dev/null +++ b/include/firm/fatfs.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - fatfs + File: fatfs.h + + Copyright 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_FATFS_H_ +#define FIRM_FATFS_H_ + +#ifdef SDK_ARM7 +#include +#include +#endif // SDK_ARM7 + + +/* FIRM_FATFS_H_ */ +#endif diff --git a/include/firm/fatfs/ARM7/fatfs_firm.h b/include/firm/fatfs/ARM7/fatfs_firm.h new file mode 100644 index 00000000..69a51da2 --- /dev/null +++ b/include/firm/fatfs/ARM7/fatfs_firm.h @@ -0,0 +1,105 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - fatfs + File: fatfs.h + + Copyright 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_FATFS_FATFS_FIRM_H_ +#define FIRM_FATFS_FATFS_FIRM_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------* + Name: FATFS_EnableAES + + Description: enable AES data path + + Arguments: slot aes key slot number + counter initial counter value + + Returns: None + *---------------------------------------------------------------------------*/ +void FATFS_EnableAES( AESKeySlot slot, const AESCounter* pCounter ); + +/*---------------------------------------------------------------------------* + Name: FATFS_DisableAES + + Description: bypass AES + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void FATFS_DisableAES( void ); + +/*---------------------------------------------------------------------------* + Name: nandRead + + Description: normal read + + Arguments: block: source sector number in NAND + dest: dest address (4 bytes alignment) + count: sectors to transfer + + Returns: None + *---------------------------------------------------------------------------*/ +void nandRead(u32 block, void *dest, u16 count); + +/*---------------------------------------------------------------------------* + Name: nandReadAES + + Description: AES read + + Arguments: block: source sector number in NAND + dest: dest address (4 bytes alignment) + count: sectors to transfer + + Returns: None + *---------------------------------------------------------------------------*/ +void nandReadAES(u32 block, void *dest, u16 count); + +/*---------------------------------------------------------------------------* + Name: FATFS_InitFIRM + + Description: init file system + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +BOOL FATFS_InitFIRM( void ); + +/*---------------------------------------------------------------------------* + Name: FATFS_MountNandFirm + + Description: mount nand partition + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +BOOL FATFS_MountNandFirm( int driveno, int partition_no ); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +/* FIRM_FATFS_FATFS_FIRM_H_ */ +#endif diff --git a/include/firm/fatfs/ARM7/fatfs_loader.h b/include/firm/fatfs/ARM7/fatfs_loader.h new file mode 100644 index 00000000..371373e9 --- /dev/null +++ b/include/firm/fatfs/ARM7/fatfs_loader.h @@ -0,0 +1,78 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - fatfs + File: fatfs_loader.h + + Copyright 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_FATFS_FATFS_LOADER_H_ +#define FIRM_FATFS_FATFS_LOADER_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------* + Name: FATFS_OpenRecentMenu + + Description: open recent menu file + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +BOOL FATFS_OpenRecentMenu( int driveno ); + +/*---------------------------------------------------------------------------* + Name: FATFS_LoadHeader + + Description: load menu header + + Arguments: None + + Returns: TRUE if success + *---------------------------------------------------------------------------*/ +BOOL FATFS_LoadHeader( void ); + +/*---------------------------------------------------------------------------* + Name: FATFS_LoadMenu + + Description: load menu binary + + Arguments: None + + Returns: TRUE if success + *---------------------------------------------------------------------------*/ +BOOL FATFS_LoadMenu( void ); + +/*---------------------------------------------------------------------------* + Name: FATFS_BootMenu + + Description: boot menu + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void FATFS_BootMenu( void ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +/* FIRM_FATFS_FATFS_LOADER_H_ */ +#endif diff --git a/include/firm/hw/ARM7/mmap_firm.h b/include/firm/hw/ARM7/mmap_firm.h index bfbcbe5d..d93fe220 100644 --- a/include/firm/hw/ARM7/mmap_firm.h +++ b/include/firm/hw/ARM7/mmap_firm.h @@ -36,6 +36,16 @@ extern "C" { #define HW_FIRM_FROM_BROM_BUF_END (HW_WRAM_AREA_END - 0x1000) // END - 4KB #define HW_FIRM_FROM_BROM_BUF_SIZE 0x3000 // 12KB +//------------------------------------- HW_FIRM_APP_BUF +#define HW_FIRM_APP_BUF (HW_MAIN_MEM_HI_EX_END - HW_FIRM_APP_BUF_SIZE) +#define HW_FIRM_APP_BUF_END (HW_FIRM_APP_BUF + HW_FIRM_APP_BUF_SIZE) +#define HW_FIRM_APP_BUF_SIZE 0x00800000 // 8MB + +//------------------------------------- HW_FIRM_BOOT_CORE +#define HW_FIRM_BOOT_CORE HW_EXT_WRAM +#define HW_FIRM_BOOT_CORE_END (HW_FIRM_BOOT_CORE + HW_FIRM_BOOT_CORE_SIZE) +#define HW_FIRM_BOOT_CORE_SIZE 0x200 // 512B + #ifdef __cplusplus } /* extern "C" */ diff --git a/include/firm/hw/ARM9/mmap_firm.h b/include/firm/hw/ARM9/mmap_firm.h index 4dea816f..6a96de0d 100644 --- a/include/firm/hw/ARM9/mmap_firm.h +++ b/include/firm/hw/ARM9/mmap_firm.h @@ -36,6 +36,15 @@ extern "C" { #define HW_FIRM_FROM_BROM_BUF_END (HW_ITCM_END - 0x1000) // END - 4KB #define HW_FIRM_FROM_BROM_BUF_SIZE 0x3000 // 12KB +//------------------------------------- HW_FIRM_APP_BUF +#define HW_FIRM_APP_BUF (HW_MAIN_MEM_HI_EX_END - HW_FIRM_APP_BUF_SIZE) +#define HW_FIRM_APP_BUF_END (HW_FIRM_APP_BUF + HW_FIRM_APP_BUF_SIZE) +#define HW_FIRM_APP_BUF_SIZE 0x00800000 // 8MB + +//------------------------------------- HW_FIRM_BOOT_CORE +#define HW_FIRM_BOOT_CORE HW_FIRM_FROM_BROM_BUF_END +#define HW_FIRM_BOOT_CORE_END (HW_FIRM_BOOT_CORE + HW_FIRM_BOOT_CORE_SIZE) +#define HW_FIRM_BOOT_CORE_SIZE 0x200 // 512B #ifdef __cplusplus } /* extern "C" */ diff --git a/include/firm/mi.h b/include/firm/mi.h index 28315ba5..427e7927 100644 --- a/include/firm/mi.h +++ b/include/firm/mi.h @@ -21,6 +21,9 @@ #include #include +#ifdef SDK_ARM9 +#include +#endif /* FIRM_MI_H_ */ #endif diff --git a/include/firm/mi/ARM9/mi_loader.h b/include/firm/mi/ARM9/mi_loader.h new file mode 100644 index 00000000..7e4b9fcf --- /dev/null +++ b/include/firm/mi/ARM9/mi_loader.h @@ -0,0 +1,66 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - mi + File: mi_loader.h + + Copyright 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_MI_LOADER_H_ +#define FIRM_MI_LOADER_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------* + Name: MI_LoadHeader + + Description: load header + + Arguments: pool pointer to the pool info for SVC_DecryptoSign + + Returns: TRUE if success + *---------------------------------------------------------------------------*/ +BOOL MI_LoadHeader( int* pool ); + +/*---------------------------------------------------------------------------* + Name: MI_LoadMenu + + Description: load menu program + + Arguments: None + + Returns: TRUE if success + *---------------------------------------------------------------------------*/ +BOOL MI_LoadMenu( void ); + +/*---------------------------------------------------------------------------* + Name: MI_BootMenu + + Description: boot menu + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void MI_BootMenu( void ); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +/* FIRM_MI_LOADER_H_ */ +#endif diff --git a/include/firm/os/common/boot.h b/include/firm/os/common/boot.h index d7ff924a..9b29b992 100644 --- a/include/firm/os/common/boot.h +++ b/include/firm/os/common/boot.h @@ -29,6 +29,8 @@ extern "C" { #endif +//---- entry point type +typedef void (*OSEntryPoint) (void); /*---------------------------------------------------------------------------* Name: OSi_Boot @@ -36,10 +38,11 @@ extern "C" { Description: boot firm Arguments: entry : entry point + w : wram settings Returns: None *---------------------------------------------------------------------------*/ -void OSi_Boot( void* entry, MIHeader_WramRegs* w, BOOL to_firm ); +void OSi_Boot( void* entry, MIHeader_WramRegs* w ); /*---------------------------------------------------------------------------* Name: OSi_Finalize @@ -52,6 +55,17 @@ void OSi_Boot( void* entry, MIHeader_WramRegs* w, BOOL to_firm ); *---------------------------------------------------------------------------*/ void OSi_Finalize(void); +/*---------------------------------------------------------------------------* + Name: OSi_ClearWorkArea + + Description: clear work area + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void OSi_ClearWorkArea( void ); + /*---------------------------------------------------------------------------* Name: OSi_GetFromBromAddr diff --git a/include/firm/pm.h b/include/firm/pm.h index 929237d2..0dac9dd7 100644 --- a/include/firm/pm.h +++ b/include/firm/pm.h @@ -1,5 +1,5 @@ /*---------------------------------------------------------------------------* - Project: TwlFirm - include - PM + Project: TwlIPL - include - pm File: pm.h Copyright 2007 Nintendo. All rights reserved. @@ -18,13 +18,11 @@ #ifndef FIRM_PM_H_ #define FIRM_PM_H_ -#include - #ifdef SDK_ARM7 -#include <../build/libraries/spi/ARM7/pm/include/pm_pmic.h> -#include <../build/libraries/spi/ARM7/pm/include/pm_pmic_ex.h> +#include +#include +#include #endif // SDK_ARM7 - /* FIRM_PM_H_ */ #endif diff --git a/include/firm/pm/ARM7/pm_init.h b/include/firm/pm/ARM7/pm_init.h new file mode 100644 index 00000000..c1be14f0 --- /dev/null +++ b/include/firm/pm/ARM7/pm_init.h @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - pm + File: pm_init.h + + Copyright 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_PM_ARM7_PM_INIT_H_ +#define FIRM_PM_ARM7_PM_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------------* + Name: PM_InitFIRM + + Description: power B/L on + + Arguments: None + + Returns: None + *---------------------------------------------------------------------------*/ +void PM_InitFIRM( void ); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_PM_ARM7_PM_INIT_H_ */ +#endif diff --git a/include/firm/pm/ARM7/pm_pmic_ex.h b/include/firm/pm/ARM7/pm_pmic_ex.h new file mode 100644 index 00000000..36515905 --- /dev/null +++ b/include/firm/pm/ARM7/pm_pmic_ex.h @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - pm + File: pm_pmic_ex.h + + Copyright 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_PM_PMIC_EX_H_ +#define FIRM_PM_PMIC_EX_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//================================================================================ +// PMIC ACCESS +//================================================================================ +/*---------------------------------------------------------------------------* + Name: PMi_SetParams + + Description: set control bit to device register + + Arguments: reg : device register + setBits : bits to set + maskBits : bits to mask + + Returns: None + *---------------------------------------------------------------------------*/ +void PMi_SetParams( u8 reg, u8 setBits, u8 maskBits ); + +/*---------------------------------------------------------------------------* + Name: PMi_SetFlags + + Description: set control bit to device register + + Arguments: reg : device register + setBits : bits to set + + Returns: None + *---------------------------------------------------------------------------*/ +void PMi_SetFlags( u8 reg, u8 setBits ); + +/*---------------------------------------------------------------------------* + Name: PMi_ResetFlags + + Description: clear control bit to device register + + Arguments: reg : device register + clrBits : bits to set + + Returns: None + *---------------------------------------------------------------------------*/ +void PMi_ResetFlags( u8 reg, u8 clrBits ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_PM_PMIC_EX_H_ */ +#endif diff --git a/include/firm/pm/ARM7/pm_reg_ex.h b/include/firm/pm/ARM7/pm_reg_ex.h new file mode 100644 index 00000000..389c2618 --- /dev/null +++ b/include/firm/pm/ARM7/pm_reg_ex.h @@ -0,0 +1,538 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - pm + File: pm_reg_ex.h + + Copyright 2006 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ +#ifndef FIRM_PM_PM_REG_EX_H_ +#define FIRM_PM_PM_REG_EX_H_ + +#define SDK_PMIC_REV 100 + +#ifdef __cplusplus +extern "C" { +#endif + + +//================================================================ +// PMIC extention register parameter +//================================================================ +//---------------- address +#define REG_PMIC_CTL2_ADDR 0x10 // R/W +#if SDK_PMIC_REV!=0 +#define REG_PMIC_OUT_CTL_ADDR 0x11 // R/W +#define REG_PMIC_TIME_CTL_ADDR 0x12 // R/W +#define REG_PMIC_PM_INFO_ADDR 0x14 // R +#define REG_PMIC_BT_INFO_ADDR 0x15 // R +#define REG_PMIC_SW_FLAGS_ADDR 0x16 // R/W +#define REG_PMIC_BT_CRCT_ADDR 0x17 // R/W +#define REG_PMIC_BT_THL_ADDR 0x18 // R/W +#define REG_PMIC_BT_THH_ADDR 0x19 // R/W +#define REG_PMIC_LED_CTL_ADDR 0x1a // R/W +#define REG_PMIC_LED12_BLK_ADDR 0x1a // R/W mirror +#define REG_PMIC_LED12_B4_ADDR 0x1b // R/W +#define REG_PMIC_LED12_B3_ADDR 0x1c // R/W +#define REG_PMIC_LED12_B2_ADDR 0x1d // R/W +#define REG_PMIC_LED12_B1_ADDR 0x1e // R/W +#define REG_PMIC_BL1_BRT_ADDR 0x1f // R/W +#define REG_PMIC_BL2_BRT_ADDR 0x20 // R/W +#else // SDK_PMIC_REV==0 +#define REG_PMIC_BT_INFO_ADDR 0x11 // R +#define REG_PMIC_SW_FLAGS_ADDR 0x12 // R/W +#define REG_PMIC_TIME_CTL_ADDR 0x15 // R/W +#define REG_PMIC_OUT_CTL_ADDR 0x16 // R/W +#define REG_PMIC_BT_CRCT_ADDR 0x18 // R/W +#define REG_PMIC_BT_THL_ADDR 0x19 // R/W +#define REG_PMIC_BT_THH_ADDR 0x1a // R/W +#define REG_PMIC_LED_CTL_ADDR 0x1c // R/W +#define REG_PMIC_LED12_B4_ADDR 0x1d // R/W +#define REG_PMIC_LED12_B3_ADDR 0x1e // R/W +#define REG_PMIC_LED12_B2_ADDR 0x1f // R/W +#define REG_PMIC_LED12_B1_ADDR 0x20 // R/W +#define REG_PMIC_LED12_BLK_ADDR 0x22 // R/W +#define REG_PMIC_BL1_BRT_ADDR 0x24 // R/W +#define REG_PMIC_BL2_BRT_ADDR 0x24 // R/W +#endif // SDK_PMIC_REV==0 +#define REG_PMIC_GPIO_CTL_ADDR 0x13 // R/W + + +//---------------- each register spec +//---- PMIC_CTL2 +#define PMIC_CTL2_RST (1<< 0) +#define PMIC_CTL2_VCNT5_BLO (1<< 1) +#define PMIC_CTL2_BKLT1 (1<< 2) +#define PMIC_CTL2_BKLT2 (1<< 3) +#define PMIC_CTL2_VLT42 (1<< 4) // ? +#define PMIC_CTL2_LCD_PWR (1<< 5) +#define PMIC_CTL2_PWR_OFF (1<< 6) + +//---- PMIC_BT_INFO +#define PMIC_BT_INFO_VLTLOW (1<< 0) +#define PMIC_BT_INFO_VLT_SHIFT 1 +#define PMIC_BT_INFO_VLT_MASK (7<< PMIC_BT_INFO_VLT_SHIFT) +#define PMIC_BT_INFO_MKR_SHIFT 5 +#define PMIC_BT_INFO_MKR_MASK (7<< PMIC_BT_INFO_MKR_SHIFT) + +//---- PMIC_SW_FLAGS +#define PMIC_SW_FLAGS_WARMBOOT (1 << 7) + +//---- PMIC_GPIO_CTL +#if SDK_PMIC_REV!=0 +#define PMIC_GPIO_CTL_O1 (1<< 0) +#define PMIC_GPIO_CTL_O2 (1<< 1) +#define PMIC_GPIO_CTL_O3 (1<< 2) +#else // SDK_PMIC_REV==0 +#define PMIC_GPIO_CTL_O1 (1<< 1) +#define PMIC_GPIO_CTL_O2 (1<< 2) +#define PMIC_GPIO_CTL_O3 (1<< 3) +#define PMIC_GPIO_CTL_AO_SHIFT 6 +#define PMIC_GPIO_CTL_AO_MASK (3<< PMIC_GPIO_CTL_SHIFT) +#endif // SDK_PMIC_REV==0 + +//---- PMIC_TIME_CTL +#if SDK_PMIC_REV!=0 +#define PMIC_TIME_CTL_OFF_SHIFT 0 +#define PMIC_TIME_CTL_OFF_MASK (0x7<< PMIC_TIME_CTL_OFF_SHIFT) +#define PMIC_TIME_CTL_ACQ_SHIFT 4 +#define PMIC_TIME_CTL_ACQ_MASK (0x3<< PMIC_TIME_CTL_ACQ_SHIFT) +#else // SDK_PMIC_REV==0 +#define PMIC_TIME_CTL_OFF_SHIFT 0 +#define PMIC_TIME_CTL_OFF_MASK (0xf<< PMIC_TIME_CTL_OFF_SHIFT) +#endif // SDK_PMIC_REV==0 + +//---- PMIC_BT_CRCT +#define PMIC_BT_CRCT_TEMP_ON (1<< 0) +#define PMIC_BT_CRCT_AMPR_ON (1<< 1) +#define PMIC_BT_CRCT_AK_SHIFT 4 +#define PMIC_BT_CRCT_AK_MASK (0x3<< PMIC_BT_CRCT_AK_SHIFT) +#define PMIC_BT_CRCT_TK_SHIFT 6 +#define PMIC_BT_CRCT_TK_MASK (0x3<< PMIC_BT_CRCT_TK_SHIFT) + +//---- PMIC_BT_THL +#define PMIC_BT_THL_TH1_SHIFT 0 +#define PMIC_BT_THL_TH1_MASK (7<< PMIC_BT_THL_TH1_SHIFT) +#define PMIC_BT_THL_TH2_SHIFT 4 +#define PMIC_BT_THL_TH2_MASK (7<< PMIC_BT_THL_TH2_SHIFT) + +//---- PMIC_BT_THH +#define PMIC_BT_THH_TH3_SHIFT 0 +#define PMIC_BT_THH_TH3_MASK (7<< PMIC_BT_THH_TH3_SHIFT) +#define PMIC_BT_THH_TH4_SHIFT 4 +#define PMIC_BT_THH_TH4_MASK (7<< PMIC_BT_THH_TH4_SHIFT) + +//---- PMIC_OUT_CTL +#if SDK_PMIC_REV!=0 +#define PMIC_OUT_CTL_V12_SHIFT 0 +#define PMIC_OUT_CTL_V12_MASK (0x1<< PMIC_OUT_CTL_V12_SHIFT) +#define PMIC_OUT_CTL_V18_SHIFT 1 +#define PMIC_OUT_CTL_V18_MASK (0x1<< PMIC_OUT_CTL_V18_SHIFT) +#define PMIC_OUT_CTL_V33_SHIFT 2 +#define PMIC_OUT_CTL_V33_MASK (0x1<< PMIC_OUT_CTL_V33_SHIFT) +#else // SDK_PMIC_REV==0 +#define PMIC_OUT_CTL_V18_SHIFT 0 +#define PMIC_OUT_CTL_V18_MASK (0x3<< PMIC_OUT_CTL_V18_SHIFT) +#define PMIC_OUT_CTL_V12_SHIFT 2 +#define PMIC_OUT_CTL_V12_MASK (0x1<< PMIC_OUT_CTL_V12_SHIFT) +#define PMIC_OUT_CTL_V33_SHIFT 3 +#define PMIC_OUT_CTL_V33_MASK (0x1<< PMIC_OUT_CTL_V33_SHIFT) +#endif // SDK_PMIC_REV==0 + +//---- PMIC_LED_CTL +#define PMIC_LED_CTL_L12_B4_ONLY (1<< 0) +#define PMIC_LED_CTL_L12_AT_BLK (1<< 1) +#if SDK_PMIC_REV!=0 +#define PMIC_LED_CTL_L12_BLK_BY_SLP (1<< 2) +#define PMIC_LED_CTL_L12_BLKF_SHIFT 4 +#define PMIC_LED_CTL_L12_BLKF_MASK (0x3<< PMIC_LED_CTL_L12_BLKF_SHIFT) +#define PMIC_LED_CTL_L12_BLKD_SHIFT 6 +#define PMIC_LED_CTL_L12_BLKD_MASK (0x3<< PMIC_LED_CTL_L12_BLKD_SHIFT) +#endif // SDK_PMIC_REV!=0 + +//---- PMIC_LED12_BLK (mirror) +#if SDK_PMIC_REV!=0 +#define PMIC_LED12_BLK_FQ_SHIFT 4 +#define PMIC_LED12_BLK_FQ_MASK (0x3<< PMIC_LED12_BLK_FQ_SHIFT) +#define PMIC_LED12_BLK_DT_SHIFT 6 +#define PMIC_LED12_BLK_DT_MASK (0x3<< PMIC_LED12_BLK_DT_SHIFT) +#else // SDK_PMIC_REV==0 +#define PMIC_LED12_BLK_FQ_SHIFT 0 +#define PMIC_LED12_BLK_FQ_MASK (0x7<< PMIC_LED12_BLK_FQ_SHIFT) +#define PMIC_LED12_BLK_DT_SHIFT 4 +#define PMIC_LED12_BLK_DT_MASK (0x3<< PMIC_LED12_BLK_DT_SHIFT) +#endif // SDK_PMIC_REV==0 + +//---- PMIC_LED12_B4 +#define PMIC_LED12_B4_L1_SHIFT 0 +#define PMIC_LED12_B4_L1_MASK (0x7<< PMIC_LED12_B4_L1_SHIFT) +#define PMIC_LED12_B4_L2_SHIFT 4 +#define PMIC_LED12_B4_L2_MASK (0x7<< PMIC_LED12_B4_L2_SHIFT) + +//---- PMIC_LED12_B3 +#define PMIC_LED12_B3_L1_SHIFT 0 +#define PMIC_LED12_B3_L1_MASK (0x7<< PMIC_LED12_B3_L1_SHIFT) +#define PMIC_LED12_B3_L2_SHIFT 4 +#define PMIC_LED12_B3_L2_MASK (0x7<< PMIC_LED12_B3_L2_SHIFT) + +//---- PMIC_LED12_B2 +#define PMIC_LED12_B2_L1_SHIFT 0 +#define PMIC_LED12_B2_L1_MASK (0x7<< PMIC_LED12_B2_L1_SHIFT) +#define PMIC_LED12_B2_L2_SHIFT 4 +#define PMIC_LED12_B2_L2_MASK (0x7<< PMIC_LED12_B2_L2_SHIFT) + +//---- PMIC_LED12_B1 +#define PMIC_LED12_B1_L1_SHIFT 0 +#define PMIC_LED12_B1_L1_MASK (0x7<< PMIC_LED12_B1_L1_SHIFT) +#define PMIC_LED12_B1_L2_SHIFT 4 +#define PMIC_LED12_B1_L2_MASK (0x7<< PMIC_LED12_B1_L2_SHIFT) + +//---- PMIC_BL1_BRT +#define PMIC_BL1_BRT_SHIFT 0 +#define PMIC_BL1_BRT_MASK (0x1f<< PMIC_BL1_BRT_SHIFT) + +//---- PMIC_BL2_BRT +#define PMIC_BL2_BRT_SHIFT 0 +#define PMIC_BL2_BRT_MASK (0x1f<< PMIC_BL2_BRT_SHIFT) + + +//---- PMIC_BT_INFO +typedef enum +{ + PMIC_BT_INFO_VLT_L1 = (0 << PMIC_BT_INFO_VLT_SHIFT), + PMIC_BT_INFO_VLT_L2 = (1 << PMIC_BT_INFO_VLT_SHIFT), + PMIC_BT_INFO_VLT_L3 = (2 << PMIC_BT_INFO_VLT_SHIFT), + PMIC_BT_INFO_VLT_L4 = (3 << PMIC_BT_INFO_VLT_SHIFT), + PMIC_BT_INFO_VLT_L5 = (4 << PMIC_BT_INFO_VLT_SHIFT) +} +PMBatteryLevel; + +//---- PMIC_TIME_CTL +typedef enum +{ +#if SDK_PMIC_REV!=0 + PMIC_TIME_CTL_OFF_125MS = (0x0 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_250MS = (0x1 << PMIC_TIME_CTL_OFF_SHIFT), // default + PMIC_TIME_CTL_OFF_500MS = (0x2 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_750MS = (0x3 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_1S = (0x4 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_2S = (0x5 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_4S = (0x6 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_8S = (0x7 << PMIC_TIME_CTL_OFF_SHIFT) +#else // SDK_PMIC_REV==0 + PMIC_TIME_CTL_OFF_100MS = (0x0 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_200MS = (0x1 << PMIC_TIME_CTL_OFF_SHIFT), // default + PMIC_TIME_CTL_OFF_300MS = (0x2 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_500MS = (0x3 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_700MS = (0x4 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_900MS = (0x5 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_1S = (0x6 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_1500MS = (0x7 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_2S = (0x8 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_2500MS = (0x9 << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_3S = (0xa << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_4S = (0xb << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_5S = (0xc << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_7S = (0xd << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_9S = (0xe << PMIC_TIME_CTL_OFF_SHIFT), + PMIC_TIME_CTL_OFF_10S = (0xf << PMIC_TIME_CTL_OFF_SHIFT) +#endif // SDK_PMIC_REV==0 +} +PMOffTime; + +//---- PMIC_BT_CRCT +typedef enum +{ + PMIC_BT_CRCT_AK_30_10 = (0 << PMIC_BT_CRCT_AK_SHIFT), + PMIC_BT_CRCT_AK_50_10 = (1 << PMIC_BT_CRCT_AK_SHIFT), // default + PMIC_BT_CRCT_AK_70_10 = (2 << PMIC_BT_CRCT_AK_SHIFT), + PMIC_BT_CRCT_AK_90_10 = (3 << PMIC_BT_CRCT_AK_SHIFT) +} +PMAmprCoeff; + +typedef enum +{ + PMIC_BT_CRCT_TK_10 = (0 << PMIC_BT_CRCT_TK_SHIFT), + PMIC_BT_CRCT_TK_15 = (1 << PMIC_BT_CRCT_TK_SHIFT), // default + PMIC_BT_CRCT_TK_20 = (2 << PMIC_BT_CRCT_TK_SHIFT), + PMIC_BT_CRCT_TK_30 = (3 << PMIC_BT_CRCT_TK_SHIFT) +} +PMTempCoeff; + +//---- PMIC_BT_THL / PMIC_BT_THH +typedef enum +{ + PMIC_BT_TH_D0 = 0, + PMIC_BT_TH_D20 = 1, + PMIC_BT_TH_D40 = 2, + PMIC_BT_TH_D60 = 3, + PMIC_BT_TH_D80 = 4, + PMIC_BT_TH_D100 = 5, + PMIC_BT_TH_D120 = 6, + PMIC_BT_TH_D140 = 7 +} +PMBatteryThresholdDownCommon; + +typedef enum +{ + PMIC_BT_THL_TH1_D0 = (0 << PMIC_BT_THL_TH1_SHIFT), + PMIC_BT_THL_TH1_D20 = (1 << PMIC_BT_THL_TH1_SHIFT), + PMIC_BT_THL_TH1_D40 = (2 << PMIC_BT_THL_TH1_SHIFT), + PMIC_BT_THL_TH1_D60 = (3 << PMIC_BT_THL_TH1_SHIFT), + PMIC_BT_THL_TH1_D80 = (4 << PMIC_BT_THL_TH1_SHIFT), + PMIC_BT_THL_TH1_D100 = (5 << PMIC_BT_THL_TH1_SHIFT), + PMIC_BT_THL_TH1_D120 = (6 << PMIC_BT_THL_TH1_SHIFT), + PMIC_BT_THL_TH1_D140 = (7 << PMIC_BT_THL_TH1_SHIFT) +} +PMBatteryThreshold1Down; + +typedef enum +{ + PMIC_BT_THL_TH2_D0 = (0 << PMIC_BT_THL_TH2_SHIFT), + PMIC_BT_THL_TH2_D20 = (1 << PMIC_BT_THL_TH2_SHIFT), + PMIC_BT_THL_TH2_D40 = (2 << PMIC_BT_THL_TH2_SHIFT), + PMIC_BT_THL_TH2_D60 = (3 << PMIC_BT_THL_TH2_SHIFT), + PMIC_BT_THL_TH2_D80 = (4 << PMIC_BT_THL_TH2_SHIFT), + PMIC_BT_THL_TH2_D100 = (5 << PMIC_BT_THL_TH2_SHIFT), + PMIC_BT_THL_TH2_D120 = (6 << PMIC_BT_THL_TH2_SHIFT), + PMIC_BT_THL_TH2_D140 = (7 << PMIC_BT_THL_TH2_SHIFT) +} +PMBatteryThreshold2Down; + +typedef enum +{ + PMIC_BT_THH_TH3_D0 = (0 << PMIC_BT_THH_TH3_SHIFT), + PMIC_BT_THH_TH3_D20 = (1 << PMIC_BT_THH_TH3_SHIFT), + PMIC_BT_THH_TH3_D40 = (2 << PMIC_BT_THH_TH3_SHIFT), + PMIC_BT_THH_TH3_D60 = (3 << PMIC_BT_THH_TH3_SHIFT), + PMIC_BT_THH_TH3_D80 = (4 << PMIC_BT_THH_TH3_SHIFT), + PMIC_BT_THH_TH3_D100 = (5 << PMIC_BT_THH_TH3_SHIFT), + PMIC_BT_THH_TH3_D120 = (6 << PMIC_BT_THH_TH3_SHIFT), + PMIC_BT_THH_TH3_D140 = (7 << PMIC_BT_THH_TH3_SHIFT) +} +PMBatteryThreshold3Down; + +typedef enum +{ + PMIC_BT_THH_TH4_D0 = (0 << PMIC_BT_THH_TH4_SHIFT), + PMIC_BT_THH_TH4_D20 = (1 << PMIC_BT_THH_TH4_SHIFT), + PMIC_BT_THH_TH4_D40 = (2 << PMIC_BT_THH_TH4_SHIFT), + PMIC_BT_THH_TH4_D60 = (3 << PMIC_BT_THH_TH4_SHIFT), + PMIC_BT_THH_TH4_D80 = (4 << PMIC_BT_THH_TH4_SHIFT), + PMIC_BT_THH_TH4_D100 = (5 << PMIC_BT_THH_TH4_SHIFT), + PMIC_BT_THH_TH4_D120 = (6 << PMIC_BT_THH_TH4_SHIFT), + PMIC_BT_THH_TH4_D140 = (7 << PMIC_BT_THH_TH4_SHIFT) +} +PMBatteryThreshold4Down; + +//---- PMIC_OUT_CTL +typedef enum +{ + PMIC_OUT_CTL_V18_PWM = (0 << PMIC_OUT_CTL_V18_SHIFT), // default + PMIC_OUT_CTL_V18_PFM = (1 << PMIC_OUT_CTL_V18_SHIFT) +} +PMPfmPwmV18; + +typedef enum +{ + PMIC_OUT_CTL_V12_PWM = (0 << PMIC_OUT_CTL_V12_SHIFT), // default + PMIC_OUT_CTL_V12_PFM = (1 << PMIC_OUT_CTL_V12_SHIFT) +} +PMPfmPwmV12; + +typedef enum +{ + PMIC_OUT_CTL_V33_PWM = (0 << PMIC_OUT_CTL_V33_SHIFT), // default + PMIC_OUT_CTL_V33_PFM = (1 << PMIC_OUT_CTL_V33_SHIFT) +} +PMPfmPwmV33; + +//---- PMIC_LED12_B4 / PMIC_LED12_B3 / PMIC_LED12_B2 / PMIC_LED12_B1 +typedef enum +{ + PMIC_LED_BRT_OFF = 0, // default + PMIC_LED_BRT_14 = 1, + PMIC_LED_BRT_28 = 2, + PMIC_LED_BRT_43 = 3, + PMIC_LED_BRT_57 = 4, + PMIC_LED_BRT_71 = 5, + PMIC_LED_BRT_85 = 6, + PMIC_LED_BRT_100 = 7 +} +PMLedBrightCommon; + +typedef enum +{ + PMIC_LED12_B4_L1_OFF = (0 << PMIC_LED12_B4_L1_SHIFT), // default + PMIC_LED12_B4_L1_14 = (1 << PMIC_LED12_B4_L1_SHIFT), + PMIC_LED12_B4_L1_28 = (2 << PMIC_LED12_B4_L1_SHIFT), + PMIC_LED12_B4_L1_43 = (3 << PMIC_LED12_B4_L1_SHIFT), + PMIC_LED12_B4_L1_57 = (4 << PMIC_LED12_B4_L1_SHIFT), + PMIC_LED12_B4_L1_71 = (5 << PMIC_LED12_B4_L1_SHIFT), + PMIC_LED12_B4_L1_85 = (6 << PMIC_LED12_B4_L1_SHIFT), + PMIC_LED12_B4_L1_100 = (7 << PMIC_LED12_B4_L1_SHIFT) +} +PMLed1Bright4; + +typedef enum +{ + PMIC_LED12_B4_L2_OFF = (0 << PMIC_LED12_B4_L2_SHIFT), // default + PMIC_LED12_B4_L2_14 = (1 << PMIC_LED12_B4_L2_SHIFT), + PMIC_LED12_B4_L2_28 = (2 << PMIC_LED12_B4_L2_SHIFT), + PMIC_LED12_B4_L2_43 = (3 << PMIC_LED12_B4_L2_SHIFT), + PMIC_LED12_B4_L2_57 = (4 << PMIC_LED12_B4_L2_SHIFT), + PMIC_LED12_B4_L2_71 = (5 << PMIC_LED12_B4_L2_SHIFT), + PMIC_LED12_B4_L2_85 = (6 << PMIC_LED12_B4_L2_SHIFT), + PMIC_LED12_B4_L2_100 = (7 << PMIC_LED12_B4_L2_SHIFT) +} +PMLed2Bright4; + +typedef enum +{ + PMIC_LED12_B3_L1_OFF = (0 << PMIC_LED12_B3_L1_SHIFT), // default + PMIC_LED12_B3_L1_14 = (1 << PMIC_LED12_B3_L1_SHIFT), + PMIC_LED12_B3_L1_28 = (2 << PMIC_LED12_B3_L1_SHIFT), + PMIC_LED12_B3_L1_43 = (3 << PMIC_LED12_B3_L1_SHIFT), + PMIC_LED12_B3_L1_57 = (4 << PMIC_LED12_B3_L1_SHIFT), + PMIC_LED12_B3_L1_71 = (5 << PMIC_LED12_B3_L1_SHIFT), + PMIC_LED12_B3_L1_85 = (6 << PMIC_LED12_B3_L1_SHIFT), + PMIC_LED12_B3_L1_100 = (7 << PMIC_LED12_B3_L1_SHIFT) +} +PMLed1Bright3; + +typedef enum +{ + PMIC_LED12_B3_L2_OFF = (0 << PMIC_LED12_B3_L2_SHIFT), // default + PMIC_LED12_B3_L2_14 = (1 << PMIC_LED12_B3_L2_SHIFT), + PMIC_LED12_B3_L2_28 = (2 << PMIC_LED12_B3_L2_SHIFT), + PMIC_LED12_B3_L2_43 = (3 << PMIC_LED12_B3_L2_SHIFT), + PMIC_LED12_B3_L2_57 = (4 << PMIC_LED12_B3_L2_SHIFT), + PMIC_LED12_B3_L2_71 = (5 << PMIC_LED12_B3_L2_SHIFT), + PMIC_LED12_B3_L2_85 = (6 << PMIC_LED12_B3_L2_SHIFT), + PMIC_LED12_B3_L2_100 = (7 << PMIC_LED12_B3_L2_SHIFT) +} +PMLed2Bright3; + +typedef enum +{ + PMIC_LED12_B2_L1_OFF = (0 << PMIC_LED12_B2_L1_SHIFT), // default + PMIC_LED12_B2_L1_14 = (1 << PMIC_LED12_B2_L1_SHIFT), + PMIC_LED12_B2_L1_28 = (2 << PMIC_LED12_B2_L1_SHIFT), + PMIC_LED12_B2_L1_43 = (3 << PMIC_LED12_B2_L1_SHIFT), + PMIC_LED12_B2_L1_57 = (4 << PMIC_LED12_B2_L1_SHIFT), + PMIC_LED12_B2_L1_71 = (5 << PMIC_LED12_B2_L1_SHIFT), + PMIC_LED12_B2_L1_85 = (6 << PMIC_LED12_B2_L1_SHIFT), + PMIC_LED12_B2_L1_100 = (7 << PMIC_LED12_B2_L1_SHIFT) +} +PMLed1Bright2; + +typedef enum +{ + PMIC_LED12_B2_L2_OFF = (0 << PMIC_LED12_B2_L2_SHIFT), // default + PMIC_LED12_B2_L2_14 = (1 << PMIC_LED12_B2_L2_SHIFT), + PMIC_LED12_B2_L2_28 = (2 << PMIC_LED12_B2_L2_SHIFT), + PMIC_LED12_B2_L2_43 = (3 << PMIC_LED12_B2_L2_SHIFT), + PMIC_LED12_B2_L2_57 = (4 << PMIC_LED12_B2_L2_SHIFT), + PMIC_LED12_B2_L2_71 = (5 << PMIC_LED12_B2_L2_SHIFT), + PMIC_LED12_B2_L2_85 = (6 << PMIC_LED12_B2_L2_SHIFT), + PMIC_LED12_B2_L2_100 = (7 << PMIC_LED12_B2_L2_SHIFT) +} +PMLed2Bright2; + +typedef enum +{ + PMIC_LED12_B1_L1_OFF = (0 << PMIC_LED12_B1_L1_SHIFT), // default + PMIC_LED12_B1_L1_14 = (1 << PMIC_LED12_B1_L1_SHIFT), + PMIC_LED12_B1_L1_28 = (2 << PMIC_LED12_B1_L1_SHIFT), + PMIC_LED12_B1_L1_43 = (3 << PMIC_LED12_B1_L1_SHIFT), + PMIC_LED12_B1_L1_57 = (4 << PMIC_LED12_B1_L1_SHIFT), + PMIC_LED12_B1_L1_71 = (5 << PMIC_LED12_B1_L1_SHIFT), + PMIC_LED12_B1_L1_85 = (6 << PMIC_LED12_B1_L1_SHIFT), + PMIC_LED12_B1_L1_100 = (7 << PMIC_LED12_B1_L1_SHIFT) +} +PMLed1Bright5; + +typedef enum +{ + PMIC_LED12_B1_L2_OFF = (0 << PMIC_LED12_B1_L2_SHIFT), // default + PMIC_LED12_B1_L2_14 = (1 << PMIC_LED12_B1_L2_SHIFT), + PMIC_LED12_B1_L2_28 = (2 << PMIC_LED12_B1_L2_SHIFT), + PMIC_LED12_B1_L2_43 = (3 << PMIC_LED12_B1_L2_SHIFT), + PMIC_LED12_B1_L2_57 = (4 << PMIC_LED12_B1_L2_SHIFT), + PMIC_LED12_B1_L2_71 = (5 << PMIC_LED12_B1_L2_SHIFT), + PMIC_LED12_B1_L2_85 = (6 << PMIC_LED12_B1_L2_SHIFT), + PMIC_LED12_B1_L2_100 = (7 << PMIC_LED12_B1_L2_SHIFT) +} +PMLed2Bright1; + +//---- PMIC_LED_CTL ( PMIC_LED12_BLK ) + +typedef enum +{ + PMIC_LED_BLK_FREQ_033HZ = 0, // default + PMIC_LED_BLK_FREQ_050HZ = 1, + PMIC_LED_BLK_FREQ_067HZ = 2, + PMIC_LED_BLK_FREQ_1HZ = 3, + PMIC_LED_BLK_FREQ_2HZ = 4, + PMIC_LED_BLK_FREQ_4HZ = 5 +} +PMLedBlinkFreqCommon; + +typedef enum +{ +#if SDK_PMIC_REV!=0 + PMIC_LED12_BLK_FREQ_041HZ = (0 << PMIC_LED_CTL_L12_BLKF_SHIFT), + PMIC_LED12_BLK_FREQ_082HZ = (1 << PMIC_LED_CTL_L12_BLKF_SHIFT), + PMIC_LED12_BLK_FREQ_2Z = (2 << PMIC_LED_CTL_L12_BLKF_SHIFT), // default + PMIC_LED12_BLK_FREQ_4HZ = (3 << PMIC_LED_CTL_L12_BLKF_SHIFT) +#else // SDK_PMIC_REV==0 + PMIC_LED12_BLK_FREQ_033HZ = (0 << PMIC_LED12_BLK_FQ_SHIFT), // default + PMIC_LED12_BLK_FREQ_050HZ = (1 << PMIC_LED12_BLK_FQ_SHIFT), + PMIC_LED12_BLK_FREQ_067HZ = (2 << PMIC_LED12_BLK_FQ_SHIFT), + PMIC_LED12_BLK_FREQ_1HZ = (3 << PMIC_LED12_BLK_FQ_SHIFT), + PMIC_LED12_BLK_FREQ_2HZ = (4 << PMIC_LED12_BLK_FQ_SHIFT), + PMIC_LED12_BLK_FREQ_4HZ = (5 << PMIC_LED12_BLK_FQ_SHIFT) +#endif // SDK_PMIC_REV==0 +} +PMLed12BlinkFreq; + +typedef enum +{ +#if SDK_PMIC_REV!=0 + PMIC_LED12_BLK_DUTY_10 = (0 << PMIC_LED_CTL_L12_BLKD_SHIFT), + PMIC_LED12_BLK_DUTY_25 = (1 << PMIC_LED_CTL_L12_BLKD_SHIFT), + PMIC_LED12_BLK_DUTY_50 = (2 << PMIC_LED_CTL_L12_BLKD_SHIFT), // default + PMIC_LED12_BLK_DUTY_75 = (3 << PMIC_LED_CTL_L12_BLKD_SHIFT) +#else // SDK_PMIC_REV==0 + PMIC_LED12_BLK_DUTY_10 = (0 << PMIC_LED12_BLK_DT_SHIFT), // default + PMIC_LED12_BLK_DUTY_25 = (1 << PMIC_LED12_BLK_DT_SHIFT), + PMIC_LED12_BLK_DUTY_50 = (2 << PMIC_LED12_BLK_DT_SHIFT), + PMIC_LED12_BLK_DUTY_75 = (3 << PMIC_LED12_BLK_DT_SHIFT) +#endif // SDK_PMIC_REV==0 +} +PMLed12BlinkDuty; + +//---- PMIC_BL1_BRT / PMIC_BL2_BRT +typedef enum +{ + PMIC_BL_BRT_MIN = 0, // default + PMIC_BL_BRT_MAX = 0x1f, + PMIC_BL_BRT_DEFAULT = 0x08 +} +PMBackLightBrightness; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_PM_PM_REG_EX_H_ */ +#endif diff --git a/include/firm/pxi.h b/include/firm/pxi.h new file mode 100644 index 00000000..b257e654 --- /dev/null +++ b/include/firm/pxi.h @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - include - PXI + File: pxi.h + + Copyright 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_PXI_H_ +#define FIRM_PXI_H_ + +#include + +#include +#include + + +/* FIRM_PXI_H_ */ +#endif diff --git a/include/firm/pxi/common/misc.h b/include/firm/pxi/common/misc.h new file mode 100644 index 00000000..5311e62d --- /dev/null +++ b/include/firm/pxi/common/misc.h @@ -0,0 +1,219 @@ +/*---------------------------------------------------------------------------* + Project: TwlFirm - -include - PXI + File: misc.h + + Copyright 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_PXI_COMMON_MISC_H_ +#define FIRM_PXI_COMMON_MISC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// PXI sync ID for bootrom +typedef enum +{ + // from ARM7 + FIRM_PXI_ID_INIT_ARM7 = 7, + FIRM_PXI_ID_LOAD_HEADER = 8, + FIRM_PXI_ID_LOAD_ARM9_STATIC = 5, + FIRM_PXI_ID_LOAD_ARM7_STATIC = 6, + FIRM_PXI_ID_LOAD_ARM9_STATIC_EX = 9, + FIRM_PXI_ID_LOAD_ARM7_STATIC_EX = 10, + FIRM_PXI_ID_LOAD_PIRIOD = 11, + + // from ARM9 + FIRM_PXI_ID_INIT_ARM9 = 9, + FIRM_PXI_ID_AUTH_HEADER = 8, + FIRM_PXI_ID_AUTH_ARM9_STATIC = 5, + FIRM_PXI_ID_AUTH_ARM7_STATIC = 6, + FIRM_PXI_ID_AUTH_ARM9_STATIC_EX = 9, + FIRM_PXI_ID_AUTH_ARM7_STATIC_EX = 10, + FIRM_PXI_ID_DONE_WRAM_SETTING = 4, + + // from both of ARM9 and ARM7 + FIRM_PXI_ID_NULL = 0, + FIRM_PXI_ID_ERR = 0xF +} +FIRMPxiID; + + +/*---------------------------------------------------------------------------* + Name: PXI_InitFifoFIRM + + Description: initialize FIFO system for bootrom + + Arguments: None. + + Returns: None. + *---------------------------------------------------------------------------*/ +void PXI_InitFifoFIRM(void); + +/*---------------------------------------------------------------------------* + Name: PXI_NotifyID + + Description: send 4bit id to other processor + + Arguments: id notifying id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_NotifyID( u32 id ); + +/*---------------------------------------------------------------------------* + Name: PXI_WaitID + + Description: Wait 4bit id from the other processor + + Arguments: id waiting id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_WaitID( u32 id ); + +/*---------------------------------------------------------------------------* + Name: PXI_RecvID + + Description: Receive 4bit id from the other processor + + Arguments: None + + Returns: id + *---------------------------------------------------------------------------*/ +u8 PXI_RecvID( void ); + +/*---------------------------------------------------------------------------* + Name: PXI_SendIDByIntf + + Description: send 4bit id to other processor + + Arguments: id notifying id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_SendIDByIntf( u32 id ); + +/*---------------------------------------------------------------------------* + Name: PXI_RecvIDByIntf + + Description: receive 4bit id from the other processor + + Arguments: None + + Returns: received id + *---------------------------------------------------------------------------*/ +u32 PXI_RecvIDByIntf( void ); + +/*---------------------------------------------------------------------------* + Name: PXI_WaitIDByIntf + + Description: Wait 4bit id from the other processor + + Arguments: id waiting id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_WaitIDByIntf( u32 id ); + +/*---------------------------------------------------------------------------* + Name: PXI_SendIDByFifo + + Description: Send 32bit-word to another CPU via FIFO + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_SendIDByFifo(PXIFifoTag tag, u32 id); + +/*---------------------------------------------------------------------------* + Name: PXI_RecvIDByFifo + + Description: Recv 32bit-word from another CPU via FIFO + + Arguments: + + Returns: if error occured, returns minus value + *---------------------------------------------------------------------------*/ +PXIFifoStatus PXI_RecvIDByFifo(PXIFifoTag tag, void* buf); + +/*---------------------------------------------------------------------------* + Name: PXI_WaitIDByFifo + + Description: Wait 32bit-word from another CPU via FIFO + + Arguments: id waiting id + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_WaitIDByFifo(PXIFifoTag tag, u32 id); + +/*---------------------------------------------------------------------------* + Name: PXI_SendDataByFifo + + Description: Send 32bit-word to another CPU via FIFO + + Arguments: + + Returns: None + *---------------------------------------------------------------------------*/ +void PXI_SendDataByFifo(PXIFifoTag tag, void* buf, int size); + +/*---------------------------------------------------------------------------* + Name: PXI_RecvDataByFifo + + Description: Recv 32bit-word to another CPU via FIFO + + Arguments: + + Returns: if error occured, returns minus value + *---------------------------------------------------------------------------*/ +PXIFifoStatus PXI_RecvDataByFifo(PXIFifoTag tag, void* buf, int max_size); + +/*---------------------------------------------------------------------------* + Name: PXI_IsSendFifoFull + + Description: Check if send fifo is full? + + Arguments: None. + + Returns: if send fifo is full + *---------------------------------------------------------------------------*/ +static inline BOOL PXI_IsSendFifoFull(void) +{ + return (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_SEND_FULL_MASK) >> REG_PXI_FIFO_CNT_SEND_FULL_SHIFT; +} + +/*---------------------------------------------------------------------------* + Name: PXI_IsRecvFifoEmpty + + Description: Check if receive fifo is empty? + + Arguments: None. + + Returns: if receive fifo is empty + *---------------------------------------------------------------------------*/ +static inline BOOL PXI_IsRecvFifoEmpty(void) +{ + return (reg_PXI_FIFO_CNT & REG_PXI_FIFO_CNT_RECV_EMP_MASK) >> REG_PXI_FIFO_CNT_RECV_EMP_SHIFT; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* FIRM_PXI_COMMON_MISC_H_ */ diff --git a/include/firm/pxi/common/regname_ex.h b/include/firm/pxi/common/regname_ex.h new file mode 100644 index 00000000..5883d6cf --- /dev/null +++ b/include/firm/pxi/common/regname_ex.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - PXI + File: regname.h + + Copyright 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. + + $Log: $ + $NoKeywords: $ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_PXI_COMMON_REGNAME_EX_H_ +#define FIRM_PXI_COMMON_REGNAME_EX_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SDK_ARM9 + +#define REG_PXI_FIFO_CNT_SEND_FULL_SHIFT REG_PXI_SUBP_FIFO_CNT_SEND_FULL_SHIFT +#define REG_PXI_FIFO_CNT_RECV_EMP_SHIFT REG_PXI_SUBP_FIFO_CNT_RECV_EMP_SHIFT + +#else // SDK_ARM7 + +#define REG_PXI_FIFO_CNT_SEND_FULL_SHIFT REG_PXI_MAINP_FIFO_CNT_SEND_FULL_SHIFT +#define REG_PXI_FIFO_CNT_RECV_EMP_SHIFT REG_PXI_MAINP_FIFO_CNT_RECV_EMP_SHIFT + +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif +/* FIRM_PXI_COMMON_REGNAME_EX_H_ */ +#endif diff --git a/include/firm/sdmc.h b/include/firm/sdmc.h new file mode 100644 index 00000000..f1560386 --- /dev/null +++ b/include/firm/sdmc.h @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL - include - sdmc + File: sdmc.h + + Copyright 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. + + $Date:: 2007-09-06$ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ + +#ifndef FIRM_SDMC_H_ +#define FIRM_SDMC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SDK_ARM9 +#else // SDK_ARM7 +#include +#include +#include +#include +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* FIRM_SDMC_H_ */ +#endif diff --git a/include/firm/specfiles/ARM7-TS-FIRM.lcf.template b/include/firm/specfiles/ARM7-TS-FIRM.lcf.template index 6194518c..4aa47cc5 100644 --- a/include/firm/specfiles/ARM7-TS-FIRM.lcf.template +++ b/include/firm/specfiles/ARM7-TS-FIRM.lcf.template @@ -1,6 +1,6 @@ #--------------------------------------------------------------------------- -# Project: TwlFirm - tools - makelcf -# File: ARM7-TS-FIRM.lcf.template +# Project: TwlSDK - include +# File: ARM7-BB.lcf.template # # Copyright 2007 Nintendo. All rights reserved. # @@ -10,30 +10,48 @@ # 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. # -# $Date:: $ -# $Rev$ -# $Author$ +# $Date:: $ +# $Rev$ +# $Author$ #--------------------------------------------------------------------------- MEMORY { - (RWX) : ORIGIN = , LENGTH = 0x0 # > + (RWX) : ORIGIN = , LENGTH = 0x0 > + - (RWX) : ORIGIN = , LENGTH = 0x0 > + (RWX) : ORIGIN = , LENGTH = 0x0 >> -# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > - - (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > - (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 >> + + F (RW) : ORIGIN = 0, LENGTH = 0x0 > + F (RW) : ORIGIN = 0, LENGTH = 0x0 > - (RWXO): ORIGIN = , LENGTH = 0x0 > + (RWXO): ORIGIN = , LENGTH = 0x0 > - arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 - check.WORKRAM (RWX) : ORIGIN = , LENGTH = 0x48000 > workram.check + + arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + check.WORKRAM (RWX) : ORIGIN = 0x037f8000, LENGTH = 0x18000 > workram.check + check.MAINMEM (RWX) : ORIGIN = 0x02fe0000, LENGTH = 0x1c000 > mainmem.check + + binary.LTDAUTOLOAD_TOP (RW) : ORIGIN = 0, LENGTH = 0x0 > + + (RWX) : ORIGIN = , LENGTH = 0x0 >> + + binary.LTDAUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 >> + + L (RW) : ORIGIN = 0, LENGTH = 0x0 > + L (RW) : ORIGIN = 0, LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + + check.LTDWRAM (RWX) : ORIGIN = 0x03000000, LENGTH = 0x40000 > ltdwram.check + check.LTDMAIN (RWX) : ORIGIN = 0x02f88000, LENGTH = 0x58000 > ltdmain.check } KEEP_SECTION { - .ctor + .sinit } SECTIONS @@ -41,140 +59,132 @@ SECTIONS ############################ STATIC ################################# .: { - ALIGNALL(4); . = ALIGN(4); # Fit to cache line - - - SEARCH_SYMBOL ; - - - # - # TEXT BLOCK: READ ONLY - # - SDK_STATIC_START =.; - SDK_STATIC_TEXT_START =.; - #:::::::::: text/rodata - OBJECT(_start,*) - crt0_firm.o (.text) - - - - - - - . = ALIGN(4); - * (.exception) - . = ALIGN(4); - SDK_STATIC_ETABLE_START =.; - EXCEPTION - SDK_STATIC_ETABLE_END =.; - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - SDK_STATIC_SINIT_START =.; - #:::::::::: ctor - - - - - - - WRITEW 0; - #:::::::::: ctor - SDK_STATIC_SINIT_END =.; - - #:::::::::: text/rodata - . = ALIGN(4); - SDK_STATIC_TEXT_END =.; + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + OBJECT(_start,*) + + + + + + + + + + + + + + + + + + + . = ALIGN(4); + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + #:::::::::: text/rodata + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + . = ALIGN(4); + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + #:::::::::: data + SDK_STATIC_DATA_END =.; + . = ALIGN(4); + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer - # - # DATA BLOCK: READ WRITE - # - SDK_STATIC_DATA_START =.; - #:::::::::: data - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: data - . = ALIGN(4); - SDK_STATIC_DATA_END =.; - SDK_STATIC_END =.; - - SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; - SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; - SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; - __sinit__ = SDK_STATIC_SINIT_START; # for static initializer - __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table - __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table } > ..bss: { - ALIGNALL(4); . = ALIGN(4); - - - SEARCH_SYMBOL ; - - - # - # BSS BLOCK - # - SDK_STATIC_BSS_START =.; - #:::::::::: bss - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: bss - . = ALIGN(4); - SDK_STATIC_BSS_END = .; - SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; - + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(4); + SDK_STATIC_BSS_END = .; + + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + } >> ############################ AUTOLOADS ############################## - SDK_AUTOLOAD.MAIN.START = 0x02380000; + SDK_AUTOLOAD.MAIN.START = 0x02fe0000; SDK_AUTOLOAD.MAIN.END = SDK_AUTOLOAD.MAIN.START; SDK_AUTOLOAD.MAIN.BSS_END = SDK_AUTOLOAD.MAIN.START; SDK_AUTOLOAD.MAIN.SIZE = 0; @@ -184,114 +194,132 @@ SECTIONS SDK_AUTOLOAD.WRAM.BSS_END = SDK_AUTOLOAD.WRAM.START; SDK_AUTOLOAD.WRAM.SIZE = 0; SDK_AUTOLOAD.WRAM.BSS_SIZE = 0; - SDK_AUTOLOAD_START = SDK_STATIC_END; - SDK_AUTOLOAD_SIZE = 0; - SDK_AUTOLOAD_NUMBER = ; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; .: { - ALIGNALL(4); . = ALIGN(4); - - - SEARCH_SYMBOL ; - - - # - # TEXT BLOCK: READ ONLY - # - SDK_AUTOLOAD__ID =; - SDK_AUTOLOAD..ID =; - SDK_AUTOLOAD..START =.; - SDK_AUTOLOAD..TEXT_START =.; - #:::::::::: text/rodata - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: text/rodata - SDK_AUTOLOAD..TEXT_END =.; - - # - # DATA BLOCK: READ WRITE BLOCK - # - SDK_AUTOLOAD..DATA_START =.; - #:::::::::: data - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: data - SDK_AUTOLOAD..DATA_END =.; - SDK_AUTOLOAD..END =.; + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + + + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + __exception_table_start__ =.; + EXCEPTION + __exception_table_end__ =.; + SDK_STATIC_ETABLE_END =.; + + + + + + + + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + . = ALIGN(4); + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + + + + + + + #:::::::::: data + SDK_AUTOLOAD..DATA_END =.; + . = ALIGN(4); + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; - SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; - SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; - SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; - SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; - } > ..bss: { - ALIGNALL(4); . = ALIGN(4); - - - SEARCH_SYMBOL ; - - - # - # BSS BLOCK - # - SDK_AUTOLOAD..BSS_START = .; - #:::::::::: bss - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: bss - . = ALIGN(4); - SDK_AUTOLOAD..BSS_END = .; - - SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; - + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(4); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + } >> @@ -310,198 +338,560 @@ SECTIONS ############################ AUTOLOAD_INFO ########################## .binary.AUTOLOAD_INFO: { - SDK_AUTOLOAD_LIST = .; - - WRITEW ADDR(.); - WRITEW SDK_AUTOLOAD..SIZE; - WRITEW SDK_AUTOLOAD..BSS_SIZE; - - SDK_AUTOLOAD_LIST_END = .; - } >> # > binary.AUTOLOAD_INFO + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + -# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; -# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + } > binary.AUTOLOAD_INFO + + SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; + SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); ############################ OVERLAYS ############################### SDK_OVERLAY_NUMBER = ; - .: + .: { - ALIGNALL(4); . = ALIGN(4); - - - SEARCH_SYMBOL ; - - - # - # TEXT BLOCK: READ ONLY - # - SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID - SDK_OVERLAY..ID =; - SDK_OVERLAY..START =.; - SDK_OVERLAY..TEXT_START =.; - #:::::::::: text/rodata - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - SDK_OVERLAY..SINIT_START =.; - #:::::::::: ctor - - - - - - - WRITEW 0; - #:::::::::: ctor - SDK_OVERLAY..SINIT_END =.; - - #:::::::::: text/rodata - . = ALIGN(4); - SDK_OVERLAY..TEXT_END =.; - - # - # DATA BLOCK: READ WRITE - # - SDK_OVERLAY..DATA_START =.; - #:::::::::: data - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: data - . = ALIGN(4); - SDK_OVERLAY..DATA_END =.; - SDK_OVERLAY..END =.; - - SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; - SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; - SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; - + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + + + + + + + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + #:::::::::: text/rodata + SDK_OVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + . = ALIGN(4); + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + #:::::::::: data + SDK_OVERLAY..DATA_END =.; + . = ALIGN(4); + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + } > - ..bss: + ..bss: { - ALIGNALL(4); . = ALIGN(4); - - - SEARCH_SYMBOL ; - - - # - # BSS BLOCK - # - SDK_OVERLAY..BSS_START = .; - #:::::::::: bss - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: bss - . = ALIGN(4); - SDK_OVERLAY..BSS_END = .; - - SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(4); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; } >> - - + ############################ ARENA ################################## .arena.MAIN: { - . = ALIGN(4); + . = ALIGN(4); SDK_SECTION_ARENA_START =.; + } > arena.MAIN - - + ############################ OVERLAYDEFS ############################ - .: + .F: { ### module information - WRITEW ADDR(.); # load address - WRITEW _start; # entry address - WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module - WRITEW _start_AutoloadDoneCallback; # callback autoload done + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done ### overlay filename - - WRITES (""); # Overlay - + + WRITES (""); # Overlay + - } > - + } > F ############################ OVERLAYTABLE ########################### - .: + .F: { - # Overlay - WRITEW ; # overlay ID - WRITEW ADDR(.); # load address - WRITEW SDK_OVERLAY..SIZE; # size of module - WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss - WRITEW SDK_OVERLAY..SINIT_START; # start address of static init - WRITEW SDK_OVERLAY..SINIT_END; # end address of static init - WRITEW ; # ROM file ID - WRITEW 0; # Reserved - + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved - - } > - + } > F + ############################ OTHERS ################################# - SDK_SUBPRIV_ARENA_LO = SDK_AUTOLOAD.MAIN.BSS_END; - SDK_WRAM_ARENA_LO = SDK_SECTION_ARENA_START; - SDK_IRQ_STACKSIZE = ; # allocated in WRAM - SDK_SYS_STACKSIZE = ; # allocated in WRAM - - # work ram size checker - SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + SDK_WRAM_ARENA_LO = SDK_AUTOLOAD.WRAM.BSS_END; + SDK_SUBPRIV_ARENA_LO = SDK_AUTOLOAD.MAIN.BSS_END; + SDK_IRQ_STACKSIZE = ; # allocated in WRAM + SDK_SYS_STACKSIZE = ; # allocated in WRAM + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + .check.WORKRAM: { - . = . + SDK_SECTION_ARENA_START - + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + . = . + SDK_AUTOLOAD.WRAM.BSS_END - SDK_AUTOLOAD.WRAM.START + 0x080 + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + } > check.WORKRAM + + .check.MAINMEM: + { + . = SDK_SUBPRIV_ARENA_LO; + + } > check.MAINMEM + + ########################### LTDAUTOLOADS ############################ + SDK_LTDAUTOLOAD.LTDMAIN.START = SDK_STATIC_BSS_END; + SDK_LTDAUTOLOAD.LTDMAIN.END = SDK_LTDAUTOLOAD.LTDMAIN.START; + SDK_LTDAUTOLOAD.LTDMAIN.BSS_END = SDK_LTDAUTOLOAD.LTDMAIN.START; + SDK_LTDAUTOLOAD.LTDMAIN.SIZE = 0; + SDK_LTDAUTOLOAD.LTDMAIN.BSS_SIZE = 0; + SDK_LTDAUTOLOAD.LTDWRAM.START = 0x03000000; + SDK_LTDAUTOLOAD.LTDWRAM.END = SDK_LTDAUTOLOAD.LTDWRAM.START; + SDK_LTDAUTOLOAD.LTDWRAM.BSS_END = SDK_LTDAUTOLOAD.LTDWRAM.START; + SDK_LTDAUTOLOAD.LTDWRAM.SIZE = 0; + SDK_LTDAUTOLOAD.LTDWRAM.BSS_SIZE = 0; + SDK_LTDAUTOLOAD_TOP_START = 0x02e80000; + SDK_LTDAUTOLOAD_TOP_SIZE = 4; # STATIC 領域が無い代わりに 4 bytes のダミーがバイナリファイルの先頭に入る # + SDK_LTDAUTOLOAD_START = SDK_LTDAUTOLOAD_TOP_START + SDK_LTDAUTOLOAD_TOP_SIZE; + SDK_LTDAUTOLOAD_SIZE = 0; + SDK_LTDAUTOLOAD_NUMBER = ; + + .binary.LTDAUTOLOAD_TOP: + { + WRITEW 0xdeadbeef; + + } > binary.LTDAUTOLOAD_TOP + + + .: + { + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + SDK_LTDAUTOLOAD__ID =; + SDK_LTDAUTOLOAD..ID =; + SDK_LTDAUTOLOAD..START =.; + # + # TEXT BLOCK: READ ONLY + # + SDK_LTDAUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + + + + + + + #:::::::::: text/rodata + SDK_LTDAUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + . = ALIGN(4); + SDK_LTDAUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + + + + + + + + + + + + + #:::::::::: data + SDK_LTDAUTOLOAD..DATA_END =.; + . = ALIGN(4); + SDK_LTDAUTOLOAD..END =.; + + SDK_LTDAUTOLOAD..TEXT_SIZE = SDK_LTDAUTOLOAD..TEXT_END - SDK_LTDAUTOLOAD..TEXT_START; + SDK_LTDAUTOLOAD..DATA_SIZE = SDK_LTDAUTOLOAD..DATA_END - SDK_LTDAUTOLOAD..DATA_START; + SDK_LTDAUTOLOAD..SIZE = SDK_LTDAUTOLOAD..END - SDK_LTDAUTOLOAD..START; + SDK_LTDAUTOLOAD_SIZE = SDK_LTDAUTOLOAD_SIZE + SDK_LTDAUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_LTDAUTOLOAD..BSS_START =.; + #:::::::::: bss + + + + + + + + + + + + + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(4); + SDK_LTDAUTOLOAD..BSS_END =.; + + SDK_LTDAUTOLOAD..BSS_SIZE = SDK_LTDAUTOLOAD..BSS_END - SDK_LTDAUTOLOAD..BSS_START; + + } >> + + + + SDK_LTDAUTOLOAD_LTDMAIN_START = SDK_LTDAUTOLOAD.LTDMAIN.START; + SDK_LTDAUTOLOAD_LTDMAIN_END = SDK_LTDAUTOLOAD.LTDMAIN.END; + SDK_LTDAUTOLOAD_LTDMAIN_BSS_END = SDK_LTDAUTOLOAD.LTDMAIN.BSS_END; + SDK_LTDAUTOLOAD_LTDMAIN_SIZE = SDK_LTDAUTOLOAD.LTDMAIN.SIZE; + SDK_LTDAUTOLOAD_LTDMAIN_BSS_SIZE = SDK_LTDAUTOLOAD.LTDMAIN.BSS_SIZE; + SDK_LTDAUTOLOAD_LTDWRAM_START = SDK_LTDAUTOLOAD.LTDWRAM.START; + SDK_LTDAUTOLOAD_LTDWRAM_END = SDK_LTDAUTOLOAD.LTDWRAM.END; + SDK_LTDAUTOLOAD_LTDWRAM_BSS_END = SDK_LTDAUTOLOAD.LTDWRAM.BSS_END; + SDK_LTDAUTOLOAD_LTDWRAM_SIZE = SDK_LTDAUTOLOAD.LTDWRAM.SIZE; + SDK_LTDAUTOLOAD_LTDWRAM_BSS_SIZE = SDK_LTDAUTOLOAD.LTDWRAM.BSS_SIZE; + + ######################### LTDAUTOLOAD_INFO ########################## + .binary.LTDAUTOLOAD_INFO: + { + + WRITEW ADDR(.); + WRITEW SDK_LTDAUTOLOAD..SIZE; + WRITEW SDK_LTDAUTOLOAD..BSS_SIZE; + + + } > binary.LTDAUTOLOAD_INFO + + SDK_LTDAUTOLOAD_LIST = SDK_LTDAUTOLOAD_START + SDK_LTDAUTOLOAD_SIZE; + SDK_LTDAUTOLOAD_LIST_END = SDK_LTDAUTOLOAD_LIST + SIZEOF(.binary.LTDAUTOLOAD_INFO); + SDK_LTDAUTOLOAD_SIZE = SDK_LTDAUTOLOAD_SIZE + SIZEOF(.binary.LTDAUTOLOAD_INFO); + + ########################### LTDOVERLAYS ############################# + SDK_LTDOVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + SDK_LTDOVERLAY__ID =; + SDK_LTDOVERLAY..ID =; + SDK_LTDOVERLAY..START =.; + # + # TEXT BLOCK: READ ONLY + # + SDK_LTDOVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + + + + + + + + + + + + + . = ALIGN(4); + SDK_LTDOVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_LTDOVERLAY..SINIT_END =.; + #:::::::::: text/rodata + SDK_LTDOVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + . = ALIGN(4); + SDK_LTDOVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + #:::::::::: data + SDK_LTDOVERLAY..DATA_END =.; + . = ALIGN(4); + SDK_LTDOVERLAY..END =.; + + SDK_LTDOVERLAY..TEXT_SIZE = SDK_LTDOVERLAY..TEXT_END - SDK_LTDOVERLAY..TEXT_START; + SDK_LTDOVERLAY..DATA_SIZE = SDK_LTDOVERLAY..DATA_END - SDK_LTDOVERLAY..DATA_START; + SDK_LTDOVERLAY..SIZE = SDK_LTDOVERLAY..END - SDK_LTDOVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); + . = ALIGN(4); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_LTDOVERLAY..BSS_START =.; + #:::::::::: bss + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(4); + SDK_LTDOVERLAY..BSS_END =.; + + SDK_LTDOVERLAY..BSS_SIZE = SDK_LTDOVERLAY..BSS_END - SDK_LTDOVERLAY..BSS_START; + + } >> + + + + ########################## LTDOVERLAYDEFS ########################### + .L: + { + ### TWL limited extended static module information + WRITEW SDK_LTDAUTOLOAD_TOP_START; # load address + WRITEW 0; # padding + WRITEW SDK_LTDAUTOLOAD_SIZE + SDK_LTDAUTOLOAD_TOP_SIZE; # size of module + WRITEW 0; # padding + + ### TWL limited overlay filename + + WRITES (""); + + + } > L + + ######################### LTDOVERLAYTABLE ########################### + .L: + { + + WRITES # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_LTDOVERLAY..SIZE; # size of module + WRITEW SDK_LTDOVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_LTDOVERLAY..SINIT_START; # start address of static init + WRITEW SDK_LTDOVERLAY..SINIT_END; # end address of static init + WRITEW # ROM file ID + WRITEW 0; # Reserved + + + } > L + + ############################ OTHERS ################################# + .check.LTDWRAM: + { + . = SDK_LTDAUTOLOAD.LTDWRAM.BSS_END; + + } > check.LTDWRAM + +# .check.LTDMAIN: +# { +# . = SDK_LTDAUTOLOAD.LTDMAIN.BSS_END; +# +# } > check.LTDMAIN + } diff --git a/include/firm/specfiles/ARM9-TS-FIRM.lcf.template b/include/firm/specfiles/ARM9-TS-FIRM.lcf.template index 0558450b..daedf10d 100644 --- a/include/firm/specfiles/ARM9-TS-FIRM.lcf.template +++ b/include/firm/specfiles/ARM9-TS-FIRM.lcf.template @@ -1,6 +1,6 @@ #--------------------------------------------------------------------------- -# Project: TwlFirm - tools - makelcf -# File: ARM9-TS-FIRM.lcf.template +# Project: TwlSDK - include +# File: ARM9-BB.lcf.template # # Copyright 2007 Nintendo. All rights reserved. # @@ -10,32 +10,52 @@ # 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. # -# $Date:: $ -# $Rev$ -# $Author$ +# $Date:: $ +# $Rev$ +# $Author$ #--------------------------------------------------------------------------- MEMORY { - (RWX) : ORIGIN = , LENGTH = 0x0 # > + (RWX) : ORIGIN = , LENGTH = 0x0 > + - (RWX) : ORIGIN = , LENGTH = 0x0 # > + (RWX) : ORIGIN = , LENGTH = 0x0 >> -# binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 > -# binary.STATIC_FOOTER (RWX) : ORIGIN = 0, LENGTH = 0x0 >> - - (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > - (RW) : ORIGIN = AFTER(), LENGTH = 0x0 > + binary.AUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 >> +# binary.STATIC_FOOTER (RWX) : ORIGIN = 0, LENGTH = 0x0 >> + + F (RW) : ORIGIN = 0, LENGTH = 0x0 > + F (RW) : ORIGIN = 0, LENGTH = 0x0 > - (RWXO): ORIGIN = , LENGTH = 0x0 > + (RWXO): ORIGIN = , LENGTH = 0x0 > - dummy.MAIN_EX (RW) : ORIGIN = 0x023e0000, LENGTH = 0x0 - arena.MAIN (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 - arena.MAIN_EX (RW) : ORIGIN = AFTER(dummy.MAIN_EX,), LENGTH = 0x0 - arena.ITCM (RW) : ORIGIN = AFTER(ITCM,), LENGTH = 0x0 - arena.DTCM (RW) : ORIGIN = AFTER(DTCM,), LENGTH = 0x0 - binary.MODULE_FILES (RW) : ORIGIN = 0x0, LENGTH = 0x0 > component.files - check.ITCM (RWX) : ORIGIN = 0x0, LENGTH = 0x08000 > itcm.check - check.DTCM (RW) : ORIGIN = 0x0, LENGTH = 0x04000 > dtcm.check + + dummy.MAIN_EX.NITRO (RW) : ORIGIN = 0x023e0000, LENGTH = 0x0 + arena.MAIN.NITRO (RW) : ORIGIN = AFTER(,), LENGTH = 0x0 + arena.MAIN_EX.NITRO (RW) : ORIGIN = AFTER(dummy.MAIN_EX.NITRO,), LENGTH = 0x0 + arena.ITCM (RW) : ORIGIN = AFTER(ITCM,), LENGTH = 0x0 + arena.DTCM (RW) : ORIGIN = AFTER(DTCM,), LENGTH = 0x0 + + check.ITCM (RW) : ORIGIN = 0x0, LENGTH = 0x08000 > itcm.check + check.DTCM (RW) : ORIGIN = 0x0, LENGTH = 0x04000 > dtcm.check + + binary.LTDAUTOLOAD_TOP (RW) : ORIGIN = 0, LENGTH = 0x0 > + + (RWX) : ORIGIN = , LENGTH = 0x0 >> + + binary.LTDAUTOLOAD_INFO (RWX) : ORIGIN = 0, LENGTH = 0x0 >> + + L (RW) : ORIGIN = 0, LENGTH = 0x0 > + L (RW) : ORIGIN = 0, LENGTH = 0x0 > + + (RWXO): ORIGIN = , LENGTH = 0x0 > + + + dummy.MAIN_EX.TWL (RW) : ORIGIN = 0x0d000000, LENGTH = 0x0 + arena.MAIN.TWL (RW) : ORIGIN = AFTER(,,LTDMAIN,), LENGTH = 0x0 + arena.MAIN_EX.TWL (RW) : ORIGIN = AFTER(dummy.MAIN_EX.TWL,,,LTDMAIN,), LENGTH = 0x0 + + binary.MODULE_FILES (RW) : ORIGIN = 0, LENGTH = 0x0 > component.files } FORCE_ACTIVE @@ -53,144 +73,147 @@ SECTIONS ############################ STATIC ################################# .: { - ALIGNALL(4); . = ALIGN(32); # Fit to cache line - - - SEARCH_SYMBOL ; - - - # - # TEXT BLOCK: READ ONLY - # - SDK_STATIC_START =.; - SDK_STATIC_TEXT_START =.; - #:::::::::: text/rodata - crt0_firm.o (.text) - libsyscall.a (.text) - crt0_firm.o (.rodata) - # - # .version セクションを追加しています。 - # このセクションに含まれる情報はロットチェックの際に - # 必要となりますので、必ずこの位置に残すようにして下さい。 - # - * (.version) - OBJECT(TwlMain,*) - - - - - - - . = ALIGN(4); - * (.exception) - . = ALIGN(4); - SDK_STATIC_ETABLE_START =.; - EXCEPTION - SDK_STATIC_ETABLE_END =.; - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - SDK_STATIC_SINIT_START =.; - #:::::::::: ctor - - - - - - - - - - - - - WRITEW 0; - #:::::::::: ctor - SDK_STATIC_SINIT_END =.; - - #:::::::::: text/rodata - . = ALIGN(32); - SDK_STATIC_TEXT_END =.; + ALIGNALL(4); + . = ALIGN(32); # Fit to cache line + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # TEXT BLOCK: READ ONLY + # + SDK_STATIC_START =.; + SDK_STATIC_TEXT_START =.; + #:::::::::: text/rodata + libsyscall.a (.text) + OBJECT(_start,*) + crt0_firm.o (.text) + crt0_firm.o (.rodata) + # + # .version セクションを追加しています。 + # このセクションに含まれる情報はロットチェックの際に + # 必要となりますので、必ずこの位置に残すようにして下さい。 + # + * (.version) + OBJECT(TwlMain,*) + + + + + + + * (.exception) + . = ALIGN(4); + SDK_STATIC_ETABLE_START =.; + __exception_table_start__ =.; + EXCEPTION + __exception_table_end__ =.; + SDK_STATIC_ETABLE_END =.; + + + + + + + + + + + + + . = ALIGN(4); + SDK_STATIC_SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_STATIC_SINIT_END =.; + #:::::::::: text/rodata + SDK_STATIC_TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + . = ALIGN(32); # Fit to cache line + SDK_STATIC_DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + . = ALIGN(4); + SDK_OVERLAY_DIGEST =.; + # NO DIGEST + SDK_OVERLAY_DIGEST_END =.; + #:::::::::: data + SDK_STATIC_DATA_END =.; + . = ALIGN(32); + SDK_STATIC_END =.; + + SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; + SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; + SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; + __sinit__ = SDK_STATIC_SINIT_START; # for static initializer - # - # DATA BLOCK: READ WRITE - # - SDK_STATIC_DATA_START =.; - #:::::::::: data - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - SDK_OVERLAY_DIGEST =.; - # NO DIGEST - SDK_OVERLAY_DIGEST_END =.; - #:::::::::: data - . = ALIGN(32); - SDK_STATIC_DATA_END =.; - SDK_STATIC_END =.; - - SDK_STATIC_TEXT_SIZE = SDK_STATIC_TEXT_END - SDK_STATIC_TEXT_START; - SDK_STATIC_DATA_SIZE = SDK_STATIC_DATA_END - SDK_STATIC_DATA_START; - SDK_STATIC_SIZE = SDK_STATIC_END - SDK_STATIC_START; - __sinit__ = SDK_STATIC_SINIT_START; # for static initializer - __exception_table_start__ = SDK_STATIC_ETABLE_START; # for exception table - __exception_table_end__ = SDK_STATIC_ETABLE_END; # for exception table } > ..bss: { - ALIGNALL(4); . = ALIGN(32); - - - SEARCH_SYMBOL ; - - - # - # BSS BLOCK - # - SDK_STATIC_BSS_START =.; - #:::::::::: bss - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: bss - . = ALIGN(32); - SDK_STATIC_BSS_END = .; - SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; + ALIGNALL(4); + . = ALIGN(32); # Fit to cache line + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_STATIC_BSS_START =.; + #:::::::::: bss + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(32); + SDK_STATIC_BSS_END = .; + + SDK_STATIC_BSS_SIZE = SDK_STATIC_BSS_END - SDK_STATIC_BSS_START; } >> @@ -201,141 +224,146 @@ SECTIONS SDK_AUTOLOAD.ITCM.BSS_END = SDK_AUTOLOAD.ITCM.START; SDK_AUTOLOAD.ITCM.SIZE = 0; SDK_AUTOLOAD.ITCM.BSS_SIZE = 0; - SDK_AUTOLOAD.DTCM.START = 0x027e0000; + SDK_AUTOLOAD.DTCM.START = 0x02fe0000; SDK_AUTOLOAD.DTCM.END = SDK_AUTOLOAD.DTCM.START; SDK_AUTOLOAD.DTCM.BSS_END = SDK_AUTOLOAD.DTCM.START; SDK_AUTOLOAD.DTCM.SIZE = 0; SDK_AUTOLOAD.DTCM.BSS_SIZE = 0; - SDK_AUTOLOAD_START = SDK_STATIC_END; - SDK_AUTOLOAD_SIZE = 0; - SDK_AUTOLOAD_NUMBER = ; + SDK_AUTOLOAD_START = SDK_STATIC_END; + SDK_AUTOLOAD_SIZE = 0; + SDK_AUTOLOAD_NUMBER = ; .: { - ALIGNALL(4); . = ALIGN(32); - - - SEARCH_SYMBOL ; - - - # - # TEXT BLOCK: READ ONLY - # - SDK_AUTOLOAD__ID =; - SDK_AUTOLOAD..ID =; - SDK_AUTOLOAD..START =.; - SDK_AUTOLOAD..TEXT_START =.; - #:::::::::: text/rodata - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: text/rodata - SDK_AUTOLOAD..TEXT_END =.; + ALIGNALL(4); + . = ALIGN(32); - # - # DATA BLOCK: READ WRITE BLOCK - # - SDK_AUTOLOAD..DATA_START =.; - #:::::::::: data - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: data - . = ALIGN(32); - SDK_AUTOLOAD..DATA_END =.; - SDK_AUTOLOAD..END =.; + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # TEXT BLOCK: READ ONLY + # + SDK_AUTOLOAD__ID =; + SDK_AUTOLOAD..ID =; + SDK_AUTOLOAD..START =.; + SDK_AUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + + + + + + + + + + + + + #:::::::::: text/rodata + SDK_AUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE BLOCK + # + . = ALIGN(32); + SDK_AUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + + + + + + + + + + + + + #:::::::::: data + SDK_AUTOLOAD..DATA_END =.; + . = ALIGN(32); + SDK_AUTOLOAD..END =.; + + SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; + SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; + SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; - SDK_AUTOLOAD..TEXT_SIZE = SDK_AUTOLOAD..TEXT_END - SDK_AUTOLOAD..TEXT_START; - SDK_AUTOLOAD..DATA_SIZE = SDK_AUTOLOAD..DATA_END - SDK_AUTOLOAD..DATA_START; - SDK_AUTOLOAD..SIZE = SDK_AUTOLOAD..END - SDK_AUTOLOAD..START; - SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SDK_AUTOLOAD..SIZE; - } > ..bss: { - ALIGNALL(4); . = ALIGN(32); - - - SEARCH_SYMBOL ; - - - # - # BSS BLOCK - # - SDK_AUTOLOAD..BSS_START = .; - #:::::::::: bss - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: bss - . = ALIGN(32); - SDK_AUTOLOAD..BSS_END = .; - - SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; - + ALIGNALL(4); + . = ALIGN(32); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL + + + # + # BSS BLOCK + # + SDK_AUTOLOAD..BSS_START = .; + #:::::::::: bss + + + + + + + + + + + + + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(32); + SDK_AUTOLOAD..BSS_END = .; + + SDK_AUTOLOAD..BSS_SIZE = SDK_AUTOLOAD..BSS_END - SDK_AUTOLOAD..BSS_START; + } >> @@ -354,249 +382,599 @@ SECTIONS ############################ AUTOLOAD_INFO ########################## .binary.AUTOLOAD_INFO: { - SDK_AUTOLOAD_LIST = .; - - WRITEW ADDR(.); - WRITEW SDK_AUTOLOAD..SIZE; - WRITEW SDK_AUTOLOAD..BSS_SIZE; - - SDK_AUTOLOAD_LIST_END = .; - } >> # > binary.AUTOLOAD_INFO + + WRITEW ADDR(.); + WRITEW SDK_AUTOLOAD..SIZE; + WRITEW SDK_AUTOLOAD..BSS_SIZE; + -# SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; -# SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); - SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); - - ############################ STATIC_FOOTER ########################## - .binary.STATIC_FOOTER: - { - WRITEW 0xdec00621; # LE(0x2106C0DE) = NITRO CODE - WRITEW _start_ModuleParams - ADDR(.); - WRITEW 0; # NO DIGEST - } >> # > binary.STATIC_FOOTER + } > binary.AUTOLOAD_INFO + SDK_AUTOLOAD_LIST = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE; + SDK_AUTOLOAD_LIST_END = SDK_AUTOLOAD_START + SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + SDK_AUTOLOAD_SIZE = SDK_AUTOLOAD_SIZE + SIZEOF(.binary.AUTOLOAD_INFO); + +# ############################ STATIC_FOOTER ########################## +# .binary.STATIC_FOOTER: +# { +# WRITEW 0xdec00621; # LE(0x2106C0DE) = NITRO CODE +# WRITEW _start_ModuleParams - ADDR(.); +# WRITEW 0; # NO DIGEST +# } > binary.STATIC_FOOTER + ############################ OVERLAYS ############################### SDK_OVERLAY_NUMBER = ; - .: + .: { - ALIGNALL(4); . = ALIGN(32); - - - SEARCH_SYMBOL ; - - - # - # TEXT BLOCK: READ ONLY - # - SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID - SDK_OVERLAY..ID =; - SDK_OVERLAY..START =.; - SDK_OVERLAY..TEXT_START =.; - #:::::::::: text/rodata - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - SDK_OVERLAY..SINIT_START =.; - #:::::::::: ctor - - - - - - - - - - - - - WRITEW 0; - #:::::::::: ctor - SDK_OVERLAY..SINIT_END =.; + ALIGNALL(4); + . = ALIGN(32); # Fit to cache line + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # TEXT BLOCK: READ ONLY + # + SDK_OVERLAY__ID =; ### SEGMENT OVERLAY ID + SDK_OVERLAY..ID =; + SDK_OVERLAY..START =.; + SDK_OVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + + + + + + + + + + + + + . = ALIGN(4); + SDK_OVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_OVERLAY..SINIT_END =.; + #:::::::::: text/rodata + SDK_OVERLAY..TEXT_END =.; - #:::::::::: text/rodata - . = ALIGN(32); - SDK_OVERLAY..TEXT_END =.; - - # - # DATA BLOCK: READ WRITE - # - SDK_OVERLAY..DATA_START =.; - #:::::::::: data - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: data - . = ALIGN(32); - SDK_OVERLAY..DATA_END =.; - SDK_OVERLAY..END =.; - - SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; - SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; - SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; + # + # DATA BLOCK: READ WRITE + # + . = ALIGN(32); + SDK_OVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + #:::::::::: data + SDK_OVERLAY..DATA_END =.; + . = ALIGN(32); + SDK_OVERLAY..END =.; + + SDK_OVERLAY..TEXT_SIZE = SDK_OVERLAY..TEXT_END - SDK_OVERLAY..TEXT_START; + SDK_OVERLAY..DATA_SIZE = SDK_OVERLAY..DATA_END - SDK_OVERLAY..DATA_START; + SDK_OVERLAY..SIZE = SDK_OVERLAY..END - SDK_OVERLAY..START; } > - ..bss: + ..bss: { - ALIGNALL(4); . = ALIGN(32); - - - SEARCH_SYMBOL ; - - - # - # BSS BLOCK - # - SDK_OVERLAY..BSS_START = .; - #:::::::::: bss - - - - - - - . = ALIGN(4); - - - - - - - . = ALIGN(4); - #:::::::::: bss - . = ALIGN(32); - SDK_OVERLAY..BSS_END = .; - - SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; + ALIGNALL(4); + . = ALIGN(32); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_OVERLAY..BSS_START = .; + #:::::::::: bss + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(32); + SDK_OVERLAY..BSS_END = .; + + SDK_OVERLAY..BSS_SIZE = SDK_OVERLAY..BSS_END - SDK_OVERLAY..BSS_START; } >> + + ############################ OVERLAYDEFS ############################ + .F: + { + ### module information + WRITEW ADDR(.); # load address + WRITEW _start; # entry address + WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module + WRITEW _start_AutoloadDoneCallback; # callback autoload done + + ### overlay filename + + WRITES (""); # Overlay + - ############################ MAIN EX ################################## - # MAIN EX Area - .dummy.MAIN_EX: + } > F + + ############################ OVERLAYTABLE ########################### + .F: + { + + WRITEW ; # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_OVERLAY..SIZE; # size of module + WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_OVERLAY..SINIT_START; # start address of static init + WRITEW SDK_OVERLAY..SINIT_END; # end address of static init + WRITEW ; # ROM file ID + WRITEW 0; # Reserved + + + } > F + + ############################ ARENA ################################## + .dummy.MAIN_EX.NITRO: { . = ALIGN(32); - } > dummy.MAIN_EX - ############################ ARENA ################################## - .arena.MAIN: + } > dummy.MAIN_EX.NITRO + + .arena.MAIN.NITRO: { - . = ALIGN(32); + . = ALIGN(32); SDK_SECTION_ARENA_START =.; - } > arena.MAIN - .arena.MAIN_EX: + } > arena.MAIN.NITRO + + .arena.MAIN_EX.NITRO: { - . = ALIGN(32); + . = ALIGN(32); SDK_SECTION_ARENA_EX_START =.; - } > arena.MAIN_EX + + } > arena.MAIN_EX.NITRO .arena.ITCM: { - . = ALIGN(32); + . = ALIGN(32); SDK_SECTION_ARENA_ITCM_START =.; + } > arena.ITCM - + .arena.DTCM: { - . = ALIGN(32); + . = ALIGN(32); SDK_SECTION_ARENA_DTCM_START =.; + } > arena.DTCM - - ############################ OVERLAYDEFS ############################ - .: - { - ### module information - WRITEW ADDR(.); # load address - WRITEW _start; # entry address - WRITEW SDK_STATIC_SIZE + SDK_AUTOLOAD_SIZE; # size of module - WRITEW _start_AutoloadDoneCallback; # callback autoload done - - ### overlay filename - - WRITES (""); # Overlay - - - } > - - ############################ OVERLAYTABLE ########################### - .: - { - - # Overlay - WRITEW ; # overlay ID - WRITEW ADDR(.); # load address - WRITEW SDK_OVERLAY..SIZE; # size of module - WRITEW SDK_OVERLAY..BSS_SIZE; # size of bss - WRITEW SDK_OVERLAY..SINIT_START; # start address of static init - WRITEW SDK_OVERLAY..SINIT_END; # end address of static init - WRITEW ; # ROM file ID - WRITEW 0; # Reserved - - - - } > - - ############################ OTHERS ################################# SDK_MAIN_ARENA_LO = SDK_SECTION_ARENA_START; SDK_IRQ_STACKSIZE = ; # allocated in DTCM SDK_SYS_STACKSIZE = ; # when 0 means all remains of DTCM - - # Module filelist - .binary.MODULE_FILES: - { - WRITES (""); - WRITES (""); - WRITES (""); - } > binary.MODULE_FILES + SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; - # ITCM/DTCM size checker => check AUTOLOAD_ITCM/DTCM .check.ITCM: { . = . + SDK_AUTOLOAD_ITCM_SIZE + SDK_AUTOLOAD_ITCM_BSS_SIZE; - } > check.ITCM + + . = . + SDK_OVERLAY..SIZE + SDK_OVERLAY..BSS_SIZE; + - SDK_SYS_STACKSIZE_SIGN = (SDK_SYS_STACKSIZE < 0x80000000) * 2 - 1; + } > check.ITCM + .check.DTCM: { . = . + SDK_AUTOLOAD_DTCM_SIZE + SDK_AUTOLOAD_DTCM_BSS_SIZE; - . = . + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; + + . = . + SDK_OVERLAY..SIZE + SDK_OVERLAY..BSS_SIZE; + + . = . + 0x080 + SDK_IRQ_STACKSIZE + SDK_SYS_STACKSIZE * SDK_SYS_STACKSIZE_SIGN; } > check.DTCM + ########################### LTDAUTOLOADS ############################ + SDK_LTDAUTOLOAD.LTDMAIN.START = SDK_STATIC_BSS_END; + SDK_LTDAUTOLOAD.LTDMAIN.END = SDK_LTDAUTOLOAD.LTDMAIN.START; + SDK_LTDAUTOLOAD.LTDMAIN.BSS_EDN = SDK_LTDAUTOLOAD.LTDMAIN.START; + SDK_LTDAUTOLOAD.LTDMAIN.SIZE = 0; + SDK_LTDAUTOLOAD.LTDMAIN.BSS_SIZE = 0; + SDK_LTDAUTOLOAD_TOP_START = 0x02400000; + SDK_LTDAUTOLOAD_TOP_SIZE = 4; # STATIC 領域が無い代わりに 4 bytes のダミーがバイナリファイルの先頭に入る # + SDK_LTDAUTOLOAD_START = SDK_LTDAUTOLOAD_TOP_START + SDK_LTDAUTOLOAD_TOP_SIZE; + SDK_LTDAUTOLOAD_SIZE = 0; + SDK_LTDAUTOLOAD_NUMBER = ; + + .binary.LTDAUTOLOAD_TOP: + { + WRITEW 0; + + } > binary.LTDAUTOLOAD_TOP + + + .: + { + ALIGNALL(4); + . = ALIGN(32); # Fit to cache line + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + SDK_LTDAUTOLOAD__ID =; + SDK_LTDAUTOLOAD..ID =; + SDK_LTDAUTOLOAD..START =.; + # + # TEXT BLOCK: READ ONLY + # + SDK_LTDAUTOLOAD..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + + + + + + + #:::::::::: text/rodata + SDK_LTDAUTOLOAD..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + . = ALIGN(32); + SDK_LTDAUTOLOAD..DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + + + + + + + #:::::::::: data + SDK_LTDAUTOLOAD..DATA_END =.; + . = ALIGN(32); + SDK_LTDAUTOLOAD..END =.; + + SDK_LTDAUTOLOAD..TEXT_SIZE = SDK_LTDAUTOLOAD..TEXT_END - SDK_LTDAUTOLOAD..TEXT_START; + SDK_LTDAUTOLOAD..DATA_SIZE = SDK_LTDAUTOLOAD..DATA_END - SDK_LTDAUTOLOAD..DATA_START; + SDK_LTDAUTOLOAD..SIZE = SDK_LTDAUTOLOAD..END - SDK_LTDAUTOLOAD..START; + SDK_LTDAUTOLOAD_SIZE = SDK_LTDAUTOLOAD_SIZE + SDK_LTDAUTOLOAD..SIZE; + + } > + + ..bss: + { + ALIGNALL(4); + . = ALIGN(32); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_LTDAUTOLOAD..BSS_START =.; + #:::::::::: bss + + + + + + + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(32); + SDK_LTDAUTOLOAD..BSS_END =.; + + SDK_LTDAUTOLOAD..BSS_SIZE = SDK_LTDAUTOLOAD..BSS_END - SDK_LTDAUTOLOAD..BSS_START; + + } >> + + + + SDK_LTDAUTOLOAD_LTDMAIN_START = SDK_LTDAUTOLOAD.LTDMAIN.START; + SDK_LTDAUTOLOAD_LTDMAIN_END = SDK_LTDAUTOLOAD.LTDMAIN.END; + SDK_LTDAUTOLOAD_LTDMAIN_BSS_END = SDK_LTDAUTOLOAD.LTDMAIN.BSS_END; + SDK_LTDAUTOLOAD_LTDMAIN_SIZE = SDK_LTDAUTOLOAD.LTDMAIN.SIZE; + SDK_LTDAUTOLOAD_LTDMAIN_BSS_SIZE = SDK_LTDAUTOLOAD.LTDMAIN.BSS_SIZE; + + ######################### LTDAUTOLOAD_INFO ########################## + .binary.LTDAUTOLOAD_INFO: + { + + WRITEW ADDR(.); + WRITEW SDK_LTDAUTOLOAD..SIZE; + WRITEW SDK_LTDAUTOLOAD..BSS_SIZE; + + + } > binary.LTDAUTOLOAD_INFO + + SDK_LTDAUTOLOAD_LIST = SDK_LTDAUTOLOAD_START + SDK_LTDAUTOLOAD_SIZE; + SDK_LTDAUTOLOAD_LIST_END = SDK_LTDAUTOLOAD_LIST + SIZEOF(.binary.LTDAUTOLOAD_INFO); + SDK_LTDAUTOLOAD_SIZE = SDK_LTDAUTOLOAD_SIZE + SIZEOF(.binary.LTDAUTOLOAD_INFO); + + ########################### LTDOVERLAYS ############################# + SDK_LTDOVERLAY_NUMBER = ; + + + .: + { + ALIGNALL(4); + . = ALIGN(32); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + SDK_LTDOVERLAY__ID =; + SDK_LTDOVERLAY..ID =; + SDK_LTDOVERLAY..START =.; + # + # TEXT BLOCK: READ ONLY + # + SDK_LTDOVERLAY..TEXT_START =.; + #:::::::::: text/rodata + + + + + + + + + + + + + + + + + + + . = ALIGN(4); + SDK_LTDOVERLAY..SINIT_START =.; + #:::::::::: ctor + + + + + + + + + + + + + WRITEW 0; + #:::::::::: ctor + SDK_LTDOVERLAY..SINIT_END =.; + #:::::::::: text/rodata + SDK_LTDOVERLAY..TEXT_END =.; + + # + # DATA BLOCK: READ WRITE + # + . = ALIGN(32); + SDK_LTDOVERLAY..DATA_START =.; + #:::::::::: data + + + + + + + + + + + + + #:::::::::: data + SDK_LTDOVERLAY..DATA_END =.; + . = ALIGN(32); + SDK_LTDOVERLAY..END =.; + + SDK_LTDOVERLAY..TEXT_SIZE = SDK_LTDOVERLAY..TEXT_END - SDK_LTDOVERLAY..TEXT_START; + SDK_LTDOVERLAY..DATA_SIZE = SDK_LTDOVERLAY..DATA_END - SDK_LTDOVERLAY..DATA_START; + SDK_LTDOVERLAY..SIZE = SDK_LTDOVERLAY..END - SDK_LTDOVERLAY..START; + + } > + + ..bss: + { + ALIGNALL(4); + . = ALIGN(32); + + # + # Definition to refer overlay segment, when same name symbols exist in multiple overlays. + # + + SEARCH_SYMBOL ; + + + # + # BSS BLOCK + # + SDK_LTDOVERLAY..BSS_START =.; + #:::::::::: bss + + + + + + + + + + + + + #:::::::::: bss + . = ALIGN(32); + SDK_LTDOVERLAY..BSS_END =.; + + SDK_LTDOVERLAY..BSS_SIZE = SDK_LTDOVERLAY..BSS_END - SDK_LTDOVERLAY..BSS_START; + + } >> + + + + ########################## LTDOVERLAYDEFS ########################### + .L: + { + ### TWL limited extended static module information + WRITEW SDK_LTDAUTOLOAD_TOP_START; # load address + WRITEW 0; # padding + WRITEW SDK_LTDAUTOLOAD_SIZE + SDK_LTDAUTOLOAD_TOP_SIZE; # size of module + WRITEW 0; # padding + + ### TWL limited overlay filename + + WRITES (""); + + + } > L + + ######################### LTDOVERLAYTABLE ########################### + .L: + { + + WRITES # overlay ID + WRITEW ADDR(.); # load address + WRITEW SDK_LTDOVERLAY..SIZE; # size of module + WRITEW SDK_LTDOVERLAY..BSS_SIZE; # size of bss + WRITEW SDK_LTDOVERLAY..SINIT_START; # start address of static init + WRITEW SDK_LTDOVERLAY..SINIT_END; # end address of static init + WRITEW # ROM file ID + WRITEW 0; # Reserved + + + } > L + + ############################ ARENA ################################## + .dummy.MAIN_EX.TWL: + { + . = ALIGN(32); + + } > dummy.MAIN_EX.TWL + + .arena.MAIN.TWL: + { + . = ALIGN(32); + SDK_LTDMAIN_ARENA_LO =.; + + } > arena.MAIN.TWL + + .arena.MAIN_EX.TWL: + { + . = ALIGN(32); + SDK_LTDMAIN_EX_ARENA_LO =.; + + } > arena.MAIN_EX.TWL + + ############################ OTHERS ################################# + # Module filelist + .binary.MODULE_FILES: + { + WRITES (""); + WRITES (""); + WRITES (""); + WRITES (""); + WRITES (""); + WRITES (""); + + } > binary.MODULE_FILES + } diff --git a/include/firm/specfiles/ARM9-TS-FIRM.lsf b/include/firm/specfiles/ARM9-TS-FIRM.lsf index 26780957..653e6b3d 100644 --- a/include/firm/specfiles/ARM9-TS-FIRM.lsf +++ b/include/firm/specfiles/ARM9-TS-FIRM.lsf @@ -40,3 +40,11 @@ Autoload DTCM Object $(OBJS_AUTOLOAD) (.bss) } +Ltdautoload LTDMAIN +{ + # NITRO/TWL 共有のオーバーレイが在る場合は、さらにその後ろに配置する必要があります。 + After $(TARGET_NAME) + Object * (.ltdmain) + Object $(OBJS_LTDAUTOLOAD) + Library $(GLTDLIBS) +}