diff options
Diffstat (limited to 'backends/platform/ds/arm9/source/fat/io_nmmc.c')
-rw-r--r-- | backends/platform/ds/arm9/source/fat/io_nmmc.c | 358 |
1 files changed, 0 insertions, 358 deletions
diff --git a/backends/platform/ds/arm9/source/fat/io_nmmc.c b/backends/platform/ds/arm9/source/fat/io_nmmc.c index 2e6b99de24..a29c26e43a 100644 --- a/backends/platform/ds/arm9/source/fat/io_nmmc.c +++ b/backends/platform/ds/arm9/source/fat/io_nmmc.c @@ -356,361 +356,3 @@ LPIO_INTERFACE NMMC_GetInterface(void) { } #endif // #ifdef SUPPORT_NMMC -/* - io_nmmc.c - - Hardware Routines for reading an SD or MMC card using - a Neoflash MK2 or MK3. - - Written by www.neoflash.com - - Submit bug reports for this device to the NeoFlash forums - - 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. - - 2006-02-09 - www.neoflash.com: - * First stable release - - 2006-02-13 - Chishm - * Added ReadMK2Config function - * Added read config test to init function so no unnecessary card commands are sent - * Changed data read and write functions to use multiple block commands -*/ - -#include "io_nmmc.h" - -#ifdef SUPPORT_NMMC - -#include <nds/card.h> - -int spi_freq = 3; - -#define MK2_CONFIG_ZIP_RAM_CLOSE (1 << 5) -#define MK2_CONFIG_GAME_FLASH_CLOSE ((1 << 4) | (1 << 0)) -//#define MK2_CONFIG_ZIP_RAM_CLOSE ((1 << 5) | (1 << 1)) -//#define MK2_CONFIG_GAME_FLASH_CLOSE (1 << 4) - -#define MMC_READ_MULTIPLE_BLOCK 18 -#define MMC_READ_BLOCK 17 -#define MMC_WRITE_MULTIPLE_BLOCK 25 -#define MMC_WRITE_BLOCK 24 -#define MMC_STOP_TRANSMISSION 12 -#define MMC_SET_BLOCKLEN 16 -#define MMC_SET_BLOCK_COUNT 23 -#define MMC_SEND_CSD 9 - -// SPI functions - -static inline void Neo_OpenSPI( u8 frequency ) -{ - CARD_CR1 = 0x0000A040 | frequency; -} - -static inline u8 Neo_SPI( u8 dataByte ) -{ - CARD_EEPDATA = dataByte; - while (CARD_CR1 & 0x80); // card busy - return CARD_EEPDATA; -} - -static inline void Neo_CloseSPI ( void ) -{ - CARD_CR1 = 0; -} - -static inline void Neo_MK2GameMode() { - Neo_OpenSPI(spi_freq); // Enable DS Card's SPI port - Neo_SPI(0xF1); // Switch to game mode - Neo_CloseSPI(); // Disable DS Card's SPI port -} - -static inline void Neo_EnableEEPROM( bool enable ) { - Neo_OpenSPI(spi_freq); - if(enable) Neo_SPI(0x06); - else Neo_SPI(0x0E); - Neo_CloseSPI(); -} - -void Neo_WriteMK2Config(u8 config) { - Neo_EnableEEPROM(true); - Neo_OpenSPI(spi_freq); - Neo_SPI(0xFA); // Send mem conf write command - Neo_SPI(0x01); // Send high byte (0x01) - Neo_SPI(config); // Send low byte - Neo_CloseSPI(); - Neo_EnableEEPROM(false); -} - -u8 Neo_ReadMK2Config(void) -{ - u8 config; - Neo_EnableEEPROM(true); - Neo_OpenSPI(spi_freq); - Neo_SPI(0xf8); // Send mem conf read command - Neo_SPI(0x01); // Send high byte - config = Neo_SPI(0x00); // Get low byte - Neo_CloseSPI(); - Neo_EnableEEPROM(false); - return config; -} - -// Low level functions - -u8 selectMMC_command [8] = {0xFF, 0x00, 0x6A, 0xDF, 0x37, 0x59, 0x33, 0xA3}; - -void Neo_SelectMMC (u8 dataByte) -{ - selectMMC_command[1] = dataByte; // Set enable / disable byte - cardWriteCommand (selectMMC_command); // Send "5. Use the EEPROM CS to access the MK2 MMC/SD card" - CARD_CR2 = CARD_ACTIVATE | CARD_nRESET; - while (CARD_CR2 & CARD_BUSY); - return; -} - -void Neo_EnableMMC( bool enable ) -{ - if ( enable == false) { - Neo_CloseSPI (); - Neo_SelectMMC (0); - Neo_SelectMMC (0); - } else { - Neo_SelectMMC (1); - Neo_SelectMMC (1); - Neo_OpenSPI (spi_freq); - } - return; -} - -void Neo_SendMMCCommand( u8 command, u32 argument ) -{ - Neo_SPI (0xFF); - Neo_SPI (command | 0x40); - Neo_SPI ((argument >> 24) & 0xff); - Neo_SPI ((argument >> 16) & 0xff); - Neo_SPI ((argument >> 8) & 0xff) ; - Neo_SPI (argument & 0xff); - Neo_SPI (0x95); - Neo_SPI (0xFF); - return; -} - -bool Neo_CheckMMCResponse( u8 response, u8 mask ) { - u32 i; - for(i=0;i<256;i++) { - if( ( Neo_SPI( 0xFF ) & mask ) == response ) - return true; - } - return false; -} - -// Neo MMC functions - -bool Neo_InitMMC() { - Neo_MK2GameMode(); - Neo_WriteMK2Config( MK2_CONFIG_ZIP_RAM_CLOSE | MK2_CONFIG_GAME_FLASH_CLOSE); - - // Make sure the configuration was accepted - if (Neo_ReadMK2Config() != (MK2_CONFIG_ZIP_RAM_CLOSE | MK2_CONFIG_GAME_FLASH_CLOSE)) { - return false; // If not, then it wasn't initialised properly - } - - return true; -} - -// Neo MMC driver functions - -bool NMMC_IsInserted(void) { - int i; - - Neo_EnableMMC( true ); // Open SPI port to MMC card - Neo_SendMMCCommand(MMC_SEND_CSD, 0); - if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - Neo_EnableMMC( false ); - return false; - } - if( Neo_CheckMMCResponse( 0xFE, 0xFF ) == false ) { // Check for Start Block token - Neo_EnableMMC( false ); - return false; - } - - // consume data from card, and send clocks. - for (i = 0; i < 28; i++) { - Neo_SPI(0xff); - } - - return true; -} - -bool NMMC_ClearStatus (void) { - u32 i; - - Neo_EnableMMC( true ); // Open SPI port to MMC card - for (i = 0; i < 10; i++) { - Neo_SPI(0xFF); // Send 10 0xFF bytes to MMC card - } - Neo_SendMMCCommand(0, 0); // Send GO_IDLE_STATE command - if( Neo_CheckMMCResponse( 0x01, 0xFF ) == false ) { // Check that it replied with 0x01 (not idle, no other error) - Neo_EnableMMC( false ); - return false; - } - for(i=0;i<256;i++) { - Neo_SendMMCCommand(1, 0); // Poll with SEND_OP_COND - if( Neo_CheckMMCResponse( 0x00, 0x01 ) == true ) { // Check for idle state - Neo_EnableMMC( false ); // Close SPI port to MMC card - return true; // Card is now idle - } - } - Neo_EnableMMC( false ); - return false; -} - -bool NMMC_Shutdown(void) { - return NMMC_ClearStatus(); -} - -bool NMMC_StartUp(void) { - int i; - int transSpeed; - if (Neo_InitMMC() == false) { - return false; - } - if (NMMC_ClearStatus() == false) { - return false; - } - Neo_EnableMMC( true ); // Open SPI port to MMC card - - // Set block length - Neo_SendMMCCommand(MMC_SET_BLOCKLEN, BYTE_PER_READ ); - if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - Neo_EnableMMC( false ); - return false; - } - - // Check if we can use a higher SPI frequency - Neo_SendMMCCommand(MMC_SEND_CSD, 0); - if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - Neo_EnableMMC( false ); - return false; - } - if( Neo_CheckMMCResponse( 0xFE, 0xFF ) == false ) { // Check for Start Block token - Neo_EnableMMC( false ); - return false; - } - for (i = 0; i < 3; i++) { - Neo_SPI(0xFF); - } - transSpeed = Neo_SPI (0xFF); - for (i = 0; i < 24; i++) { - Neo_SPI(0xFF); - } - if ((transSpeed & 0xf0) >= 0x30) { - spi_freq = 0; - } - - Neo_EnableMMC( false ); - return true; -} - - -bool NMMC_WriteSectors (u32 sector, u8 numSecs, void* buffer) -{ - u32 i; - u8 *p=buffer; - - int totalSecs = (numSecs == 0) ? 256 : numSecs; - sector *= BYTE_PER_READ; - - Neo_EnableMMC( true ); // Open SPI port to MMC card - Neo_SendMMCCommand( 25, sector ); - if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - Neo_EnableMMC( false ); - return false; - } - - while (totalSecs--) { - Neo_SPI( 0xFC ); // Send Start Block token - for( i = 0; i < BYTE_PER_READ; i++ ) // Send a block of data - Neo_SPI( *p++ ); - Neo_SPI( 0xFF ); // Send fake CRC16 - Neo_SPI( 0xFF ); // Send fake CRC16 - - if( ( Neo_SPI( 0xFF ) & 0x0F ) != 0x05 ) { // Make sure the block was accepted - Neo_EnableMMC( false ); - return false; - } - while( Neo_SPI( 0xFF ) == 0x00 ); // Wait for the block to be written - } - - // Stop transmission block - Neo_SPI( 0xFD ); // Send Stop Transmission Block token - for( i = 0; i < BYTE_PER_READ; i++ ) // Send a block of fake data - Neo_SPI( 0xFF ); - Neo_SPI( 0xFF ); // Send fake CRC16 - Neo_SPI( 0xFF ); // Send fake CRC16 - - Neo_SPI (0xFF); // Send 8 clocks - while( Neo_SPI( 0xFF ) == 0x00 ); // Wait for the busy signal to clear - - - for ( i = 0; i < 0x10; i++) { - Neo_SPI (0xFF); // Send clocks for the MMC card to finish what it's doing - } - - Neo_EnableMMC( false ); // Close SPI port to MMC card - return true; -} - -bool NMMC_ReadSectors (u32 sector, u8 numSecs, void* buffer) -{ - u32 i; - u8 *p=buffer; - - int totalSecs = (numSecs == 0) ? 256 : numSecs; - sector *= BYTE_PER_READ; - - Neo_EnableMMC( true ); // Open SPI port to MMC card - - while (totalSecs--) { - Neo_SendMMCCommand(MMC_READ_BLOCK, sector ); - if( Neo_CheckMMCResponse( 0x00, 0xFF ) == false ) { // Make sure no errors occured - Neo_EnableMMC( false ); - return false; - } - - if( Neo_CheckMMCResponse( 0xFE, 0xFF ) == false ) { // Check for Start Block token - Neo_EnableMMC( false ); - return false; - } - for( i = 0; i < BYTE_PER_READ; i++ ) // Read in a block of data - *p++ = Neo_SPI( 0xFF ); - Neo_SPI( 0xFF ); // Ignore CRC16 - Neo_SPI( 0xFF ); // Ignore CRC16 - sector += BYTE_PER_READ; - } - - Neo_EnableMMC( false ); // Close SPI port to MMC card - return true; -} - - -IO_INTERFACE io_nmmc = { - DEVICE_TYPE_NMMC, - FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE, - (FN_MEDIUM_STARTUP)&NMMC_StartUp, - (FN_MEDIUM_ISINSERTED)&NMMC_IsInserted, - (FN_MEDIUM_READSECTORS)&NMMC_ReadSectors, - (FN_MEDIUM_WRITESECTORS)&NMMC_WriteSectors, - (FN_MEDIUM_CLEARSTATUS)&NMMC_ClearStatus, - (FN_MEDIUM_SHUTDOWN)&NMMC_Shutdown -} ; - - -LPIO_INTERFACE NMMC_GetInterface(void) { - return &io_nmmc ; -} - -#endif // #ifdef SUPPORT_NMMC |