Skip to content

Instantly share code, notes, and snippets.

@handsomematt
Last active August 23, 2017 08:54
Show Gist options
  • Save handsomematt/e0fb9ad138d7761239c21d81d9598d88 to your computer and use it in GitHub Desktop.
Save handsomematt/e0fb9ad138d7761239c21d81d9598d88 to your computer and use it in GitHub Desktop.
dstt notes

Cart Command

int CartCommand(char cmd, int data1, int data2)
{
  CARDCMD_0 = cmd;
  CARDCMD_1 = BYTE3(data1);
  CARDCMD_2 = (unsigned int)(data1 << 8) >> 24;
  CARDCMD_3 = (unsigned int)(data1 << 16) >> 24;
  CARDCMD_4 = data1;
  CARDCMD_5 = (unsigned int)(data2 << 16) >> 24;
  CARDCMD_6 = data2;
  CARDCMD_7 = 0;
  REG_ROMCTRL = 0xA7180000;
  while ( !(REG_ROMCTRL & 0x800000) )
    ;
  return CARD_DATA_RD;
}

A lot of the cart commands can be mapped similarly to the commands seen on page 20 here: https://media.digikey.com/pdf/Data%20Sheets/Macronix/MX29LV160D(T,B).pdf

0x86 & 0x87

CartCommand(0x86, 0, 0); appears before most 0x87 commands, 0x87 appears to interface directly to the chip documented above.

Read Mode Command

CartCommand(0x87, Addr, Data);

Reset Mode Command

CartCommand(0x87, 0xXXXX, 0xF0);

Erasing

Two types of erase commands, depends on the flashchip detected.

Type 1 can be implemented as the C below where it simply erases 4 bytes at a time.

void Erase_Type1(uint32_t offset, uint32_t length)
{
    CartCommand(0x86, 0, 0);
    CartCommand(0x87, 0x5555, 0xAA);
    CartCommand(0x87, 0x2AAA, 0x55);
    CartCommand(0x87, 0x5555, 0x80); // unlocks the flashchip?
    CartCommand(0x87, 0x5555, 0xAA);
    CartCommand(0x87, 0x2AAA, 0x55);

    CartCommand(0x87, offset, 0x30);

    uint32_t end_offset = offset + length;
    while(offset > end_offset)
    {
        while ( CartCommand(0, offset, 0) != 0xFFFFFFFF )
        {
            // wait until it's 0xFFFFFFFF
            // todo: some sort of timeout = failure
        }

        offset += 4;
    }

    CartCommand(0x87, 0x5555, 0xF0);    
}

Type 2 is different

void Erase_Type2(uint32_t offset, uint32_t length)
{
    CartCommand(0x86, 0, 0);
    CartCommand(0x87, offset, 0x50);
    CartCommand(0x87, offset, 0x20);
    CartCommand(0x87, offset, 0xD0);

    uint32_t result = CartCommand(0, offset, 0);
    while ( !(result & 0x80) )
        result = CartCommand(0, offset, 0);

    CartCommand(0x87, offset, 0x50);
    CartCommand(0x87, offset, 0xFF);

    uint32_t end_offset = offset + length;
    while(offset > end_offset)
    {
        while ( CartCommand(0, offset, 0) != 0xFFFFFFFF )
        {
            // wait until it's 0xFFFFFFFF
            // todo: some sort of timeout = failure
        }

        offset += 4;
    }
}

Writing

void Write_Type1(uint32_t offset, uint32_t data)
{
    CartCommand(0x86, 0, 0);
    CartCommand(0x87, offset, 0x50);
    CartCommand(0x87, offset, 0x40);
    CartCommand(0x87, offset, data);

    uint32_t result = CartCommand(0, offset & 0xFFFFFFFC, 0);
    while ( !(result & 0x80) )
        result = CartCommand(0, offset & 0xFFFFFFFC, 0);

    CartCommand(0x87, offset, 0x50);
    CartCommand(0x87, offset, 0xFF);
}
void Write_Type2(uint32_t offset, uint32_t data)
{
    CartCommand(0x86, 0, 0);
    CartCommand(0x87, 0x5555, 0xAA);
    CartCommand(0x87, 0x2AAA, 0x55);
    CartCommand(0x87, 0x5555, 0xA0);
    CartCommand(0x87, offset, data);

    // todo: this has some crazy weird alignment shit
    CartCommand(0, offset & 0xFFFFFFFC, 0);


    CartCommand(0x87, 0x5555, 0xF0);
}

Flashchip detection

DSTT can have a lot of different flash chips, some are writeable, some are not. You can get information about the flash chip with the following cart commands:

CartCommand(0x86, 0, 0);
CartCommand(0x87, 0x5555, 0xAA);
CartCommand(0x87, 0x2AAA, 0x55);
CartCommand(0x87, 0x5555, 0x90);
g_DeviceType = CartCommand(0, 0, 0);
CartCommand(0x87, 0x5555, 0xF0);
if ( (g_DeviceType & 0xFF00FFFF) != 0x7F003437
&& (g_DeviceType & 0xFF00FFFF) != 0x7F00B537
&& (unsigned __int16)g_DeviceType != 0x41F
&& (unsigned __int16)g_DeviceType != 0x51F )
{
CartCommand(0x87, 0x5555, 0xAA);
CartCommand(0x87, 0x2AAA, 0x55);
CartCommand(0x87, 0x5555, 0x90);
v0 = CartCommand(0, 0x100, 0);
CartCommand(0x87, 0x5555, 0xF0);
if ( (unsigned __int16)v0 == 0xBA1C || (unsigned __int16)v0 == 0xB91C )
    g_DeviceType = v0;
}

Supported Flashchips

  • 0x041F "ATMEL AT49BV001A(N)T"
  • 0x051F "ATMEL AT49BV001A(N)"
  • 0x1A37 "AMIC A29L800T"
  • 0x3437 "AMIC A29L400T"
  • 0x49B0 "SHARP LH28F160BGHB-BTL"
  • 0x49C2 "MACRONIX MX29LV160BB"
  • 0x5BC2 "MACRONIX MX29LV800B"
  • 0x80BF "SST SST39LF/VF400A"
  • 0x9020 "ST M28W160(B)T"
  • 0x9089 "INTEL 28F160B3T"
  • 0x9120 "ST M28W160(B)B"
  • 0x912C "MICRON MT28F160A3-B"
  • 0x9189 "INTEL 28F160B3B"
  • 0x922C "MICRON MT28F160C3(4)-T"
  • 0x9289 "INTEL 28F800B3T"
  • 0x9320 "ST M28W800BB"
  • 0x9389 "INTEL 28F800B3B"
  • 0x9689 "INTEL 28F320B3T"
  • 0x9789 "INTEL 28F320B3B"
  • 0x9B37 "AMIC A29L800U"
  • 0xA01F "ATMEL AT49BV8192*"
  • 0xA31F "ATMEL AT49BV8192*T"
  • 0xA7C2 "MACRONIX MX29LV320T"
  • 0xA8C2 "MACRONIX MX29LV320B"
  • 0xBA01 "SPANSION Am29LV400BB"
  • 0xBA04 "SPANSION MBM29LV400BC"
  • 0xBA1C "EON EN29LV400AB"
  • 0xBA4A "ESI ES29LV400DB"
  • 0xBAC2 "MACRONIX MX29LV400B"
  • 0xB537 "AMIC A29L400U"
  • 0xB91C "EON EN29LV400AT"
  • 0xC11F "ATMEL AT49BV802*"
  • 0xC298 "TOSHIBA TC58FVT160A"
  • 0xC31F "ATMEL AT49BV802*T"
  • 0xC420 "ST M29W160BT"
  • 0xC4C2 "MACRONIX MX29LV160BT"
  • 0xEF20 "ST M29W400B"

Unsupported Flashchips

  • 0x0B8A "DSTTi :P"
  • 0x23AD "BRIGHT MICRO. BM29LV400T"
  • 0x4398 "TOSHIBA TC58FVB160A"
  • 0x4920 "ST M29W160BB"
  • 0x5B20 "ST M29W800BT"
  • 0x68B0 "SHARP LH28F160BG(H)-TTL"
  • 0x69B0 "SHARP LH28F160BG(H)-BTL"
  • 0x81BF "SST SST39LF/VF800A"
  • 0x89BF "SST SST39LF/VF200A"
  • 0x902C "MICRON MT28F160A3-T"
  • 0x9220 "ST M28W800BT"
  • 0x932C "MICRON MT28F160C3(4)-B"
  • 0x9489 "INTEL 28F400B3T"
  • 0x9589 "INTEL 28F400B3B"
  • 0xABAD "BRIGHT MICRO. BM29LV400B"
  • 0xB901 "SPANSION Am29LV400BT"
  • 0xB904 "SPANSION MBM29LV400TC"
  • 0xB9C2 "MACRONIX MX29LV400T"
  • 0xB94A "ESI ES29LV400DT"
  • 0xB952 "ALIANCE SEMI. AS29LV400T"
  • 0xBA52 "ALIANCE SEMI. AS29LV400B"
  • 0xCE20 "ST M28W160E(C)T"
  • 0xCF20 "ST M28W160E(C)B"
  • 0xD089 "INTEL 28F016B3T"
  • 0xD189 "INTEL 28F016B3B"
  • 0xD289 "INTEL 28F008B3T"
  • 0xD389 "INTEL 28F008B3B"
  • 0xD489 "INTEL 28F004B3T"
  • 0xD520 "ST M29F400BT"
  • 0xD589 "INTEL 28F004B3B"
  • 0xD620 "ST M29F400BB"
  • 0xD689 "INTEL 28F032B3T"
  • 0xD720 "ST M29W800AT"
  • 0xD789 "INTEL 28F032B3B"
  • 0xDAC2 "MACRONIX MX29LV800T"
  • 0xEE20 "ST M29W400T"
enum supported_flashtypes : __int16
{
ATMEL_AT49BV001AT = 0x41F,
ATMEL_AT49BV001A = 0x51F,
AMIC_A29L800T = 0x1A37,
AMIC_A29L400T = 0x3437,
SHARP_LH28F160BGHB_BTL = 0x49B0,
MACRONIX_MX29LV160BB = 0x49C2,
MACRONIX_MX29LV800B = 0x5BC2,
SST_SST39LFVF400A = 0x80BF,
ST_M28W160T = 0x9020,
INTEL_28F160B3T = 0x9089,
ST_M28W160B = 0x9120,
INTEL_28F160B3B = 0x9189,
MICRON_MT28F160C3_T = 0x922C,
INTEL_28F800B3T = 0x9289,
ST_M28W800BB = 0x9320,
INTEL_28F800B3B = 0x9389,
INTEL_28F320B3T = 0x9689,
INTEL_28F320B3B = 0x9789,
AMIC_A29L800U = 0x9B37,
MACRONIX_MX29LV320T = 0xA7C2,
MACRONIX_MX29LV320B = 0xA8C2,
SPANSION_Am29LV400BB = 0xBA01,
SPANSION_MBM29LV400BC = 0xBA04,
EON_EN29LV400AB = 0xBA1C,
MACRONIX_MX29LV400B = 0xBAC2,
AMIC_A29L400U = 0xB537,
EON_EN29LV400AT = 0xB91C,
TOSHIBA_TC58FVT160A = 0xC298,
ST_M29W160BT = 0xC420,
MACRONIX_MX29LV160BT = 0xC4C2,
ST_M29W400B = 0xEF20
};
enum unsupported_flashtypes : __int16
{
DSTTi = 0xB8A,
TOSHIBA_TC58FVB160A = 0x4398,
ST_M29W160BB = 0x4920,
ST_M29W800BT = 0x5B20,
SHARP_LH28F160BG_TTL = 0x68B0,
SHARP_LH28F160BG_BTL = 0x69B0,
SST_SST39LFVF800A = 0x81BF,
SST_SST39LFVF200A = 0x89BF,
ST_M28W800BT = 0x9220
MICRON_MT28F160C3_B = 0x932C,
INTEL_28F400B3T = 0x9489,
INTEL_28F400B3B = 0x9589,
SPANSION_Am29LV400BT = 0xB901,
SPANSION_MBM29LV400TC = 0xB904,
MACRONIX_MX29LV400T = 0xB9C2,
ST_M28W160ET = 0xCE20,
ST_M28W160EB = 0xCF20,
INTEL_28F016B3T = 0xD089,
INTEL_28F016B3B = 0xD189,
INTEL_28F008B3T = 0xD289,
INTEL_28F008B3B = 0xD389,
INTEL_28F004B3T = 0xD489,
INTEL_28F004B3B = 0xD589,
INTEL_28F032B3T = 0xD689,
ST_M29W800AT = 0xD720,
INTEL_28F032B3B = 0xD789,
MACRONIX_MX29LV800T = 0xDAC2,
ST_M29W400T = 0xEE20,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment