Thanks for the feedback :- ) and thanks for pointing out that there's a thread about suggesting a Nintendo DSi section. Somebody seems to have just added voting to that thread. If you (don't) a want DSi section: Click here
http://gbatemp.net/threads/nintendo-dsi-section.393580/ and vote yes/no.
Current news: Tested writing some kilobytes of data to the sd/mmc DATA16 and DATA32 registers (without actually sending any commands, so the data just stays in the fifo without transfer to sd/mmc card). Turned out that there actually several fifos in the console:
- DATA16 has
two FIFOs, each with a capacity of 200h bytes
- DATA32 has at least one FIFO, with a capacity of 200h bytes
The two DATA16 fifos are apparently swapped after each transfer, so the CPU can access one FIFO, simultaneously with the sd/mmc card accessing the other FIFO.
Writing some kbytes to DATA16 resulted in the first 200h bytes being stored in the first FIFO (let's call it FIFO_A), and the last 200h bytes being stored in the other FIFO (FIFO_B), ie. once when FIFO_A was filled, all further writes seem to have been written (and overwritten) to FIFO_B.
After filling the FIFO's, reading returned the content of FIFO_B, reading beyond end of FIFO_B wrapped to FIFO_A (and stayed wrapping within FIFO_A on further reads).
SOFT_RESET is also having some effect on the DATA16 fifos: It's resetting the read pointer to 'First halfword of FIFO_A'. And, during softreset, reading from the FIFO is disabled (trying to read from it does just return 0000h, even if the two FIFO's do contain only nonzero values) (softreset doesn't change or zerofill the FIFO content though; the old content is getting accessible again once when releasing softreset).
The DATA32 can FIFO can hold another 200h bytes, this seems to be some patchwork for supporting 32bit DMA's an a chip that was originally designed to support only 16bit access (it would have been more elegant to add 32bit support to the existing two FIFOs, instead of coming up with the extra DATA32 FIFO). During actual memory card transfers, the 32bit FIFO is probably copied to/from one of the 16bit FIFOs (if so, then the FIFO32 data should be visible in FIFO16; but that's still to be tested).
Writing some kbytes to FIFO32 results in the first 200h bytes being stored in the 32bit FIFO (the remaining written bytes seem to be lost; unless there's a second 32bit FIFO state, but I haven't found anything hinting in that direction, and a second FIFO wouldn't be too useful in this place). After doing writing: Reading returns those first 200h bytes, and further reads are then stuck on returning the last word (ie. byte number 1FCh..1FFh). I've tried softreset and some other potention "fifo-clear" bits, but haven't yet found anything that would release the 32bit FIFO from being "stuck on last word".
The capacity for the 16bit & 32bit FIFOs depends on the corresponding BLK_LEN registers. Default size (and maximum size) would be 200h bytes, but when using smaller BLK_LEN settings, then the FIFOs are getting smaller accordingly (ie. switching from FIFO_A to FIFO_B occurs after writing less than 200h bytes, and reading from 32bit FIFO gets stuck after less than 200h bytes). The BLK_LEN registers are a bit complicated (when writing 'invalid' values to them):
DATA16_BLK_LEN can be set to 0..200h (trying to write 201h..3FFh will be automatically changed to 200h, ie. when reading BLK_LEN you'll see 200h instead of the written value). Of that possible settings, values 1..200h are working as planned (and for 16bit access, they are rounded-up to multiples of two bytes, although the for the serial bus, the hardware should use the actual length without rounding). The special case is 0, which seems to act same as 200h (at least concerning reading/writing the FIFO register; don't know what happens on the serial bus when using BLK_LEN=0).
DATA32_BLK_LEN can be set to 0..3FFh (reading BLK_LEN returns that values unchanged). But internally, the values are saturated to min 1 word, and max 80h words (ie. 4..200h bytes, or maybe 1..200h bytes) (for 32bit access, the values
are rounded-up to multiples of 4 bytes, but don't know if that rounding is also applied to the serial transfer length; it shouldn't be rounded, but maybe they didn't care if FIFO32 was intended only for bigger data blocks).
And, one more thing about DATA32 mode: The firmware seems to be writing the first data block to the 32bit FIFO
before even sending the WRITE_MULTIPLE command via SD_CMD register. Don't know
why the firmware is doing that though, it would be more efficient to send the data after the SD_CMD write (so the FIFO could be filled while the command & response are being transferred via serial bus). Normmatt seems to have gotten data writes working without that data-before-command ordering.
The only case where data-before-command might be useful & efficient would be sending the data before the
previous WRITE_MULTIPLE (and GET_STATUS) commands have finished. That would allow to write multiple clusters without losing speed at cluster boundaries. Only, error handling might be a nightmare: Sensing possible write errors at a time when there's already data for the next write in the FIFO - such a thing should be implemented only if you know what you are doing (and ideally, also have a way to test errors, using worn out memory cards, or some special hardware that can automatically generate errors for testing).