diff options
author | Neil Millstone | 2006-11-03 23:16:29 +0000 |
---|---|---|
committer | Neil Millstone | 2006-11-03 23:16:29 +0000 |
commit | ea6663fdfa5f2b9d8351f9b06219d0dae1494a6c (patch) | |
tree | 76a1ca3e5f5672194133d3bdaabdb038275a0e57 /backends/platform/ds/arm9/source/fat/io_m3sd.c | |
parent | d5608e82edb4a73f6ab30a8db9a79dc16ed2ed9f (diff) | |
download | scummvm-rg350-ea6663fdfa5f2b9d8351f9b06219d0dae1494a6c.tar.gz scummvm-rg350-ea6663fdfa5f2b9d8351f9b06219d0dae1494a6c.tar.bz2 scummvm-rg350-ea6663fdfa5f2b9d8351f9b06219d0dae1494a6c.zip |
Merging in changes made in branch for 0.9.1 release into trunk
svn-id: r24596
Diffstat (limited to 'backends/platform/ds/arm9/source/fat/io_m3sd.c')
-rw-r--r-- | backends/platform/ds/arm9/source/fat/io_m3sd.c | 739 |
1 files changed, 445 insertions, 294 deletions
diff --git a/backends/platform/ds/arm9/source/fat/io_m3sd.c b/backends/platform/ds/arm9/source/fat/io_m3sd.c index 823f94a280..26f249279a 100644 --- a/backends/platform/ds/arm9/source/fat/io_m3sd.c +++ b/backends/platform/ds/arm9/source/fat/io_m3sd.c @@ -1,375 +1,526 @@ /* - io_m3sd.c based on io_m3cf.c by SaTa. + io_m3sd.c - io_m3cf.c based on - - compact_flash.c - By chishm (Michael Chisholm) - - Hardware Routines for reading a compact flash card - using the M3 Perfect CF Adapter - - CF routines modified with help from Darkfader - - This software is completely free. No warranty is provided. - If you use it, please give me credit and email me about your - project at chishm@hotmail.com - - See gba_nds_fat.txt for help and license details. + Hardware Routines for reading a Secure Digital card + using the M3 SD + + Some code based on M3 SD drivers supplied by M3Adapter. + Some code written by SaTa may have been unknowingly used. + + Copyright (c) 2006 Michael "Chishm" Chisholm + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + 2006-07-25 - Chishm + * Improved startup function that doesn't delay hundreds of seconds + before reporting no card inserted. + * Fixed writeData function to timeout on error + * writeSectors function now wait until the card is ready before continuing with a transfer + + 2006-08-05 - Chishm + * Tries multiple times to get a Relative Card Address at startup + + 2006-08-07 - Chishm + * Moved the SD initialization to a common function */ - #include "io_m3sd.h" +#include "io_sd_common.h" +#include "io_m3_common.h" +//#include "common.h" +#include "disc_io.h" +#include <stdio.h> + +#define BYTES_PER_READ 512 + +//--------------------------------------------------------------- +// M3SD register addresses + +#define REG_M3SD_DIR (*(vu16*)0x08800000) // direction control register +#define REG_M3SD_DAT (*(vu16*)0x09000000) // SD data line, 8 bits at a time +#define REG_M3SD_CMD (*(vu16*)0x09200000) // SD command byte +#define REG_M3SD_ARGH (*(vu16*)0x09400000) // SD command argument, high halfword +#define REG_M3SD_ARGL (*(vu16*)0x09600000) // SD command argument, low halfword +#define REG_M3SD_STS (*(vu16*)0x09800000) // command and status register + +//--------------------------------------------------------------- +// Send / receive timeouts, to stop infinite wait loops +#define NUM_STARTUP_CLOCKS 100 // Number of empty (0xFF when sending) bytes to send/receive to/from the card +#define TRANSMIT_TIMEOUT 20000 // Time to wait for the M3 to respond to transmit or receive requests +#define RESPONSE_TIMEOUT 256 // Number of clocks sent to the SD card before giving up +#define WRITE_TIMEOUT 3000 // Time to wait for the card to finish writing + +//--------------------------------------------------------------- +// Variables required for tracking SD state +static u32 _M3SD_relativeCardAddress = 0; // Preshifted Relative Card Address + +//--------------------------------------------------------------- +// Internal M3 SD functions + +static inline void _M3SD_unlock (void) { + _M3_changeMode (M3_MODE_MEDIA); +} -#ifdef SUPPORT_M3SD - -//SD dir control bit cmddir=bit0 clken=bit1 -//output -#define SDDIR (*(volatile u16*)0x8800000) - -//SD send get control bit send=bit0 get=bit1 -//output -#define SDCON (*(volatile u16*)0x9800000) - -//SD output data obyte[7:0]=AD[7:0] -//output -#define SDODA (*(volatile u16*)0x9000000) - -//SD input data AD[7:0]=ibyte[7:0] -//input -#define SDIDA (*(volatile u16*)0x9000000) - -//readsector data1 -#define SDIDA1 (*(volatile u16*)0x9200000) +static inline bool _M3SD_waitOnBusy (void) { + int i = 0; + while ( (REG_M3SD_STS & 0x01) == 0x00) { + i++; + if (i >= TRANSMIT_TIMEOUT) { + return false; + } + } + return true; +} -//readsector data2 -#define SDIDA2 (*(volatile u16*)0x9400000) +static inline bool _M3SD_waitForDataReady (void) { + int i = 0; + while ( (REG_M3SD_STS & 0x40) == 0x00) { + i++; + if (i >= TRANSMIT_TIMEOUT) { + return false; + } + } + return true; +} -//readsector data3 -#define SDIDA3 (*(volatile u16*)0x9600000) -//SD stutas cmdneg=bit0 cmdpos=bit1 issend=bit2 isget=bit3 -//input -#define SDSTA (*(volatile u16*)0x9800000) +static bool _M3SD_sendCommand (u16 command, u32 argument) { + REG_M3SD_STS = 0x8; + REG_M3SD_CMD = 0x40 + command; // Include the start bit + REG_M3SD_ARGH = argument >> 16; + REG_M3SD_ARGL = argument; + // The CRC7 of the command is calculated by the M3 + + REG_M3SD_DIR=0x29; + if (!_M3SD_waitOnBusy()) { + REG_M3SD_DIR=0x09; + return false; + } + REG_M3SD_DIR=0x09; + return true; +} -//#define CARD_TIMEOUT 10000000 // Updated due to suggestion from SaTa, otherwise card will timeout sometimes on a write -#define CARD_TIMEOUT (500*100) // M3SD timeout nomal:500 +static bool _M3SD_sendByte (u8 byte) { + int i = 0; + REG_M3SD_DAT = byte; + REG_M3SD_DIR = 0x03; + REG_M3SD_STS = 0x01; + while ((REG_M3SD_STS & 0x04) == 0) { + i++; + if (i >= TRANSMIT_TIMEOUT) { + return false; + } + } + return true; +} -//====================================================== -bool M3SD_read1sector(u32 sectorn,u32 TAddr) -{ - u32 i; - int w; - - SDCON=0x8; // bit3:コマンドモード? - SDIDA1=0x40+17; // コマンド CMD17 - SDIDA2=(sectorn>>7);// セクタH 9ビット=アドレスH 16ビット - SDIDA3=(sectorn<<9);// セクタL 7ビット=アドレスL 16ビット - SDDIR=0x29; // コマンド送信? - i=0; - - while ( ((SDSTA&0x01) != 0x01)&&(i < CARD_TIMEOUT) ) - { +static u8 _M3SD_getByte (void) { + int i; + // Request 8 bits of data from the SD's CMD pin + REG_M3SD_DIR = 0x02; + REG_M3SD_STS = 0x02; + // Wait for the data to be ready + i = 0; + while ((REG_M3SD_STS & 0x08) == 0) { i++; + if (i >= TRANSMIT_TIMEOUT) { + // Return an empty byte if a timeout occurs + return 0xFF; + } } - SDDIR=0x09; - i=0; - SDDIR=0x49; - while ( ((SDSTA&0x40) != 0x40)&&(i < CARD_TIMEOUT) ) - { + i = 0; + while ((REG_M3SD_STS & 0x08) != 0) { i++; + if (i >= TRANSMIT_TIMEOUT) { + // Return an empty byte if a timeout occurs + return 0xFF; + } } - SDDIR=0x09; - - SDDIR=0x8;//cmd input clken=0 datadir input clock=0 - SDCON=0x4;//send=0 get=0 en25=1 cmd1=0 - - w = SDDIR; - for(w=0;w<0x100;w++) - { - u16 d16; - u8 *d8=(u8 *)&d16; -// *(u16*)(TAddr+w*2) = SDDIR; // 16bit - d16 = SDDIR; // 16bit - *(u8 *)(TAddr+w*2) =d8[0]; - *(u8 *)(TAddr+w*2+1) =d8[1]; - + // Return the data + return (REG_M3SD_DAT & 0xff); +} + +// Returns the response from the SD card to a previous command. +static bool _M3SD_getResponse (u8* dest, u32 length) { + u32 i; + u8 dataByte; + int shiftAmount; + + // Wait for the card to be non-busy + for (i = 0; i < RESPONSE_TIMEOUT; i++) { + dataByte = _M3SD_getByte(); + if (dataByte != SD_CARD_BUSY) { + break; + } } - w = SDDIR; - w = SDDIR; - if (i >= CARD_TIMEOUT) + if (dest == NULL) { + return true; + } + + // Still busy after the timeout has passed + if (dataByte == 0xff) { return false; - - return true; + } -} -//================================================== - + // Read response into buffer + for ( i = 0; i < length; i++) { + dest[i] = dataByte; + dataByte = _M3SD_getByte(); + } + // dataByte will contain the last piece of the response + + // Send 16 more clocks, 8 more than the delay required between a response and the next command + i = _M3SD_getByte(); + i = _M3SD_getByte(); + + // Shift response so that the bytes are correctly aligned + // The register may not contain properly aligned data + for (shiftAmount = 0; ((dest[0] << shiftAmount) & 0x80) != 0x00; shiftAmount++) { + if (shiftAmount >= 7) { + return false; + } + } + + for (i = 0; i < length - 1; i++) { + dest[i] = (dest[i] << shiftAmount) | (dest[i+1] >> (8-shiftAmount)); + } + // Get the last piece of the response from dataByte + dest[i] = (dest[i] << shiftAmount) | (dataByte >> (8-shiftAmount)); -//====================================================== -void SD_crc16(u16* buff,u16 num,u16* crc16buff); -void SD_data_write(u16 *buff,u16* crc16buff); + return true; +} -u16 Hal4ATA_StatusByte; -void Hal4ATA_GetStatus(void) -{ - Hal4ATA_StatusByte = SDSTA; +static inline bool _M3SD_getResponse_R1 (u8* dest) { + return _M3SD_getResponse (dest, 6); } -bool Hal4ATA_WaitOnBusy(void) -{ - Hal4ATA_GetStatus(); - while ( (Hal4ATA_StatusByte & 0x01) != 0x1) - { - Hal4ATA_GetStatus(); - } - return TRUE; +static inline bool _M3SD_getResponse_R1b (u8* dest) { + return _M3SD_getResponse (dest, 6); } -bool Hal4ATA_WaitOnBusyNDrdy(void) -{ - Hal4ATA_GetStatus(); - while ( (Hal4ATA_StatusByte&0x40) !=0x40) - { - Hal4ATA_GetStatus(); - } - return TRUE; +static inline bool _M3SD_getResponse_R2 (u8* dest) { + return _M3SD_getResponse (dest, 17); } +static inline bool _M3SD_getResponse_R3 (u8* dest) { + return _M3SD_getResponse (dest, 6); +} -void SendCommand(u16 command, u32 sectorn) -{ - SDCON=0x8; - SDIDA1=0x40+command; - SDIDA2=(sectorn>>7); - SDIDA3=(sectorn<<9); +static inline bool _M3SD_getResponse_R6 (u8* dest) { + return _M3SD_getResponse (dest, 6); +} - SDDIR=0x29; - Hal4ATA_WaitOnBusy(); - SDDIR=0x09; +static void _M3SD_sendClocks (u32 numClocks) { + while (numClocks--) { + _M3SD_sendByte(0xff); + } } +static void _M3SD_getClocks (u32 numClocks) { + while (numClocks--) { + _M3SD_getByte(); + } +} -#define DMA3SAD *(u32*)0x040000D4 -#define DMA3DAD *(u32*)0x040000D8 -#define DMA3CNT *(u32*)0x040000DC +bool _M3SD_cmd_6byte_response (u8* responseBuffer, u8 command, u32 data) { + _M3SD_sendCommand (command, data); + return _M3SD_getResponse (responseBuffer, 6); +} -void DMA3(u32 src, u32 dst, u32 cnt) -{ - DMA3SAD=src; - DMA3DAD=dst; - DMA3CNT=cnt; +bool _M3SD_cmd_17byte_response (u8* responseBuffer, u8 command, u32 data) { + _M3SD_sendCommand (command, data); + return _M3SD_getResponse (responseBuffer, 17); } +static bool _M3SD_initCard (void) { + // Give the card time to stabilise + _M3SD_sendClocks (NUM_STARTUP_CLOCKS); + + // Reset the card + if (!_M3SD_sendCommand (GO_IDLE_STATE, 0)) { + return false; + } + _M3SD_getClocks (NUM_STARTUP_CLOCKS); -void PassRespond(u32 num) -{ - u32 i,dmanum; + // Card is now reset, including it's address + _M3SD_relativeCardAddress = 0; - dmanum=(64+(num<<3))>>2; - SDDIR=0x8; - SDCON=0x4; - DMA3(0x8800000,(u32)&i,0x80400000+dmanum); + // Init the card + return _SD_InitCard (_M3SD_cmd_6byte_response, + _M3SD_cmd_17byte_response, + true, + &_M3SD_relativeCardAddress); } -//bool M3SD_write1sector(u32 sectorn,u16 * p) -bool M3SD_write1sector(u32 sectorn,u32 p) -{ - u16 crc[4]; - - SendCommand(24,sectorn); - PassRespond(6); - - SDDIR=0x4; - SDCON=0x0; +static bool _M3SD_readData (void* buffer) { + u32 i; + u8* buff_u8 = (u8*)buffer; + u16* buff = (u16*)buffer; + u16 temp; - SD_crc16((u16 *)p,512,crc); - SD_data_write((u16 *)p,crc); + REG_M3SD_DIR = 0x49; + if (!_M3SD_waitForDataReady()) { + REG_M3SD_DIR = 0x09; + return false; + } + REG_M3SD_DIR = 0x09; + + REG_M3SD_DIR = 0x8; + REG_M3SD_STS = 0x4; + + i = REG_M3SD_DIR; + // Read data + i=256; + if ((u32)buff_u8 & 0x01) { + while(i--) + { + temp = REG_M3SD_DIR; + *buff_u8++ = temp & 0xFF; + *buff_u8++ = temp >> 8; + } + } else { + while(i--) + *buff++ = REG_M3SD_DIR; + } + // Read end checksum + i = REG_M3SD_DIR + REG_M3SD_DIR + REG_M3SD_DIR + REG_M3SD_DIR; + return true; -} -//================================================== - - -// GBAMP CF Addresses - -#define M3_REG_STS *(vu16*)(0x09800000) // Status of the CF Card / Device control +} -#define M3_DATA (vu16*)(0x08800000) // Pointer to buffer of CF data transered from card +static void _M3SD_clkout (void) { + REG_M3SD_DIR = 0x4; + REG_M3SD_DIR = 0xc; +/* __asm volatile ( + "ldr r1, =0x08800000 \n" + "mov r0, #0x04 \n" + "strh r0, [r1] \n" + "mov r0, r0 \n" + "mov r0, r0 \n" + "mov r0, #0x0c \n" + "strh r0, [r1] \n" + : // Outputs + : // Inputs + : "r0", "r1" // Clobber list + );*/ +} -// CF Card status -#define CF_STS_INSERTED1 0x20 -#define CF_STS_INSERTED2 0x30 +static void _M3SD_clkin (void) { + REG_M3SD_DIR = 0x0; + REG_M3SD_DIR = 0x8; +/* __asm volatile ( + "ldr r1, =0x08800000 \n" + "mov r0, #0x00 \n" + "strh r0, [r1] \n" + "mov r0, r0 \n" + "mov r0, r0 \n" + "mov r0, #0x08 \n" + "strh r0, [r1] \n" + : // Outputs + : // Inputs + : "r0", "r1" // Clobber list + );*/ +} -/*----------------------------------------------------------------- -M3SD_IsInserted -Is a compact flash card inserted? -bool return OUT: true if a CF card is inserted ------------------------------------------------------------------*/ -bool M3SD_IsInserted (void) -{ +static bool _M3SD_writeData (u8* data, u8* crc) { int i; - u16 sta; - // Change register, then check if value did change - M3_REG_STS = CF_STS_INSERTED1; - - for(i=0;i<CARD_TIMEOUT;i++) - { - sta=M3_REG_STS; - if((sta == CF_STS_INSERTED1)||(sta == CF_STS_INSERTED2)) - { - return true; - //break; + u8 temp; + + do { + _M3SD_clkin(); + } while ((REG_M3SD_DAT & 0x100) == 0); + + REG_M3SD_DAT = 0; // Start bit + + _M3SD_clkout(); + + for (i = 0; i < BYTES_PER_READ; i++) { + temp = (*data++); + REG_M3SD_DAT = temp >> 4; + _M3SD_clkout(); + REG_M3SD_DAT = temp; + _M3SD_clkout(); + } + + if (crc != NULL) { + for (i = 0; i < 8; i++) { + temp = (*crc++); + REG_M3SD_DAT = temp >> 4; + _M3SD_clkout(); + REG_M3SD_DAT = temp; + _M3SD_clkout(); } } - return false; -// return ( (sta == CF_STS_INSERTED1)||(sta == CF_STS_INSERTED2) ); -// return true; + i = 32; + while (i--) { + temp += 2; // a NOP to stop the compiler optimising out the loop + } + + for (i = 0; i < 32; i++) { + REG_M3SD_DAT = 0xff; + _M3SD_clkout(); + } + + do { + _M3SD_clkin(); + } while ((REG_M3SD_DAT & 0x100) == 0); + + return true; } +//--------------------------------------------------------------- +// Functions needed for the external interface -/*----------------------------------------------------------------- -M3SD_ClearStatus -Tries to make the CF card go back to idle mode -bool return OUT: true if a CF card is idle ------------------------------------------------------------------*/ -bool M3SD_ClearStatus (void) -{ - -// int i=SDDIR; - int i; - u16 sta; +bool _M3SD_startUp (void) { + _M3SD_unlock(); + return _M3SD_initCard(); +} - i = 0; - M3_REG_STS = CF_STS_INSERTED1; - while (i < CARD_TIMEOUT) - { - sta=M3_REG_STS; - if( (sta == CF_STS_INSERTED1)||(sta == CF_STS_INSERTED2) )break; - i++; +bool _M3SD_isInserted (void) { + u8 responseBuffer [6]; + // Make sure the card receives the command + if (!_M3SD_sendCommand (SEND_STATUS, 0)) { + return false; } - if (i >= CARD_TIMEOUT) + // Make sure the card responds + if (!_M3SD_getResponse_R1 (responseBuffer)) { return false; - + } + // Make sure the card responded correctly + if (responseBuffer[0] != SEND_STATUS) { + return false; + } return true; } +bool _M3SD_readSectors (u32 sector, u32 numSectors, void* buffer) { + u32 i; + u8* dest = (u8*) buffer; + u8 responseBuffer[6]; + + if (numSectors == 1) { + // If it's only reading one sector, use the (slightly faster) READ_SINGLE_BLOCK + if (!_M3SD_sendCommand (READ_SINGLE_BLOCK, sector * BYTES_PER_READ)) { + return false; + } -/*----------------------------------------------------------------- -M3SD_ReadSectors -Read 512 byte sector numbered "sector" into "buffer" -u32 sector IN: address of first 512 byte sector on CF card to read -u8 numSecs IN: number of 512 byte sectors to read, - 1 to 256 sectors can be read, 0 = 256 -void* buffer OUT: pointer to 512 byte buffer to store data in -bool return OUT: true if successful ------------------------------------------------------------------*/ -bool M3SD_ReadSectors (u32 sector, u8 numSecs, void* buffer) -{ - + if (!_M3SD_readData (buffer)) { + return false; + } - //void M3SD_read1sector(u32 sectorn,u32 TAddr) - bool r=true; - int i; - for(i=0;i<numSecs;i++) - { - if(M3SD_read1sector(i + sector , 512*i + (u32) buffer )==false) - { - r=false; - break; + } else { + // Stream the required number of sectors from the card + if (!_M3SD_sendCommand (READ_MULTIPLE_BLOCK, sector * BYTES_PER_READ)) { + return false; } + + for(i=0; i < numSectors; i++, dest+=BYTES_PER_READ) { + if (!_M3SD_readData(dest)) { + return false; + } + REG_M3SD_STS = 0x8; + } + + // Stop the streaming + _M3SD_sendCommand (STOP_TRANSMISSION, 0); + _M3SD_getResponse_R1b (responseBuffer); } - return r; + return true; } - - -/*----------------------------------------------------------------- -M3SD_WriteSectors -Write 512 byte sector numbered "sector" from "buffer" -u32 sector IN: address of 512 byte sector on CF card to read -u8 numSecs IN: number of 512 byte sectors to read, - 1 to 256 sectors can be read, 0 = 256 -void* buffer IN: pointer to 512 byte buffer to read data from -bool return OUT: true if successful ------------------------------------------------------------------*/ -bool M3SD_WriteSectors (u32 sector, u8 numSecs, void* buffer) -{ - - bool r=true; +bool _M3SD_writeSectors (u32 sector, u32 numSectors, const void* buffer) { + u8 crc[8]; + u8 responseBuffer[6]; + u32 offset = sector * BYTES_PER_READ; + u8* data = (u8*) buffer; int i; - for(i=0;i<numSecs;i++) - { - if(M3SD_write1sector(i + sector , 512*i + (u32) buffer )==false) - { - r=false; - break; + // Precalculate the data CRC + _SD_CRC16 ( data, BYTES_PER_READ, crc); + + while (numSectors--) { + // Send a single sector write command + _M3SD_sendCommand (WRITE_BLOCK, offset); + if (!_M3SD_getResponse_R1 (responseBuffer)) { + return false; } + + REG_M3SD_DIR = 0x4; + REG_M3SD_STS = 0x0; + + // Send the data + if (! _M3SD_writeData( data, crc)) { + return false; + } + + if (numSectors > 0) { + offset += BYTES_PER_READ; + data += BYTES_PER_READ; + // Calculate the next CRC while waiting for the card to finish writing + _SD_CRC16 ( data, BYTES_PER_READ, crc); + } + + // Wait for the card to be ready for the next transfer + i = WRITE_TIMEOUT; + responseBuffer[3] = 0; + do { + _M3SD_sendCommand (SEND_STATUS, _M3SD_relativeCardAddress); + _M3SD_getResponse_R1 (responseBuffer); + i--; + if (i <= 0) { + return false; + } + } while (((responseBuffer[3] & 0x1f) != ((SD_STATE_TRAN << 1) | READY_FOR_DATA))); } - return r; - -// return false; - + + return true; } - -/*----------------------------------------------------------------- -M3_Unlock -Returns true if M3 was unlocked, false if failed -Added by MightyMax ------------------------------------------------------------------*/ -bool M3SD_Unlock(void) -{ - - // run unlock sequence - volatile unsigned short tmp ; - tmp = *(volatile unsigned short *)0x08000000 ; - tmp = *(volatile unsigned short *)0x08E00002 ; - tmp = *(volatile unsigned short *)0x0800000E ; - tmp = *(volatile unsigned short *)0x08801FFC ; - tmp = *(volatile unsigned short *)0x0800104A ; - tmp = *(volatile unsigned short *)0x08800612 ; - tmp = *(volatile unsigned short *)0x08000000 ; - tmp = *(volatile unsigned short *)0x08801B66 ; - tmp = *(volatile unsigned short *)0x08800006 ; - tmp = *(volatile unsigned short *)0x08000000 ; - // test that we have register access - vu16 sta; - sta=M3_REG_STS; - sta=M3_REG_STS; - if( (sta == CF_STS_INSERTED1)||(sta == CF_STS_INSERTED2) )return true; - - return false; +bool _M3SD_clearStatus (void) { + return _M3SD_initCard (); } -bool M3SD_Shutdown(void) { - return M3SD_ClearStatus() ; -} ; - -bool M3SD_StartUp(void) { - return M3SD_Unlock() ; -} ; - +bool _M3SD_shutdown (void) { + _M3_changeMode (M3_MODE_ROM); + return true; +} -IO_INTERFACE io_m3sd = { +IO_INTERFACE _io_m3sd = { DEVICE_TYPE_M3SD, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE, - (FN_MEDIUM_STARTUP)&M3SD_StartUp, - (FN_MEDIUM_ISINSERTED)&M3SD_IsInserted, - (FN_MEDIUM_READSECTORS)&M3SD_ReadSectors, - (FN_MEDIUM_WRITESECTORS)&M3SD_WriteSectors, - (FN_MEDIUM_CLEARSTATUS)&M3SD_ClearStatus, - (FN_MEDIUM_SHUTDOWN)&M3SD_Shutdown + FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_SLOT_GBA, + (FN_MEDIUM_STARTUP)&_M3SD_startUp, + (FN_MEDIUM_ISINSERTED)&_M3SD_isInserted, + (FN_MEDIUM_READSECTORS)&_M3SD_readSectors, + (FN_MEDIUM_WRITESECTORS)&_M3SD_writeSectors, + (FN_MEDIUM_CLEARSTATUS)&_M3SD_clearStatus, + (FN_MEDIUM_SHUTDOWN)&_M3SD_shutdown } ; - LPIO_INTERFACE M3SD_GetInterface(void) { - return &io_m3sd ; + return &_io_m3sd ; } ; -#endif // SUPPORT_M3CF |