PS2 [MX4SIO/SIO2SD] SD Card Adapter and SD-driver for the PS2 SIO2 interface

@Takeshi
More speed, more possibilities I guess. It's about the same speed as the IOP itself, lol. So perhaps we can offload bit reversal and crc. But every feature has to be programmed, and I'm a little sceptical about the 1 day time it takes to program a uC.

@wisi
I've been experimenting with https://github.com/Krasutski/sdcard_spi_driver driver inside sio2sd_bd the last couple of days. I can see it do interesting things that result in perhaps better SD card compatibility. The initialization sequence gets completed and seems more stable than what's in the current driver, but I cannot get it to read data yet (even at low clock speeds, still returns only 0xFF).
I've connected the read/write function calls from the library to the 'sendCmd' function. That seems to work (I know it will be slow, for now). But this library also uses the CS/SS line a lot, by calling _io->select() and _io->relese(). Then each time flushing a single byte read/write, like so:
Code:
    /* Dummy byte and chip enable */
    _io->wr_rd_byte(DUMMY_BYTE);
    _io->select();

   // do stuff...

    /* Chip disable and dummy byte */
    _io->relese();
    _io->wr_rd_byte(DUMMY_BYTE);
Do you know if we can do this with the sio2 also? Or should I try to completely remove all chip/slave-selecting code?
 
@Takeshi
I agree with your observations.
Many MCUs maybe can be used, but I guess somebody will have to actually do a test with some MCU to truly see the effects of using one. Once a test with an MCU has been made, maybe more requirements will appear.
I am considering doing such tests, but I am not yet sure if I will.
Does this MCU supports reprogramming (in this case by data read from SPI)?

@Takeshi EDIT:
I didn't check if there are variants of the ST MCUs with USB, most likely there are, but for example the https://www.microchip.com/wwwproducts/en/PIC32MX220F032B has USB and is around the same price (50MHz though), so that should be considered two.

But every feature has to be programmed, and I'm a little sceptical about the 1 day time it takes to program a uC.
That was more, assuming that it only controls the /CS line and does nothing more sophisticated. In that case it gets a certain command, then enables the line / gets another command - disables it. And I think that can be easily done in a day - setting-up the SPI, and other devices and adding the necessary code for detecting the commands.
Such projects do tend to introduce small problems that take a lot of time to find a workaround for, so if anything like that happens, - like the MCU not reacting fast-enough, if a slow one is used, then it can take a lot longer. ;)

@Maximus32
That is the whole problem with SIO2 - we have no separate control of the /CS(/SS) line - it is activated *only* over each byte and if I am not mistaken, then deactivated for a short while and then activated over the next. One way to work-around that would be a fast external MCU which we could send commands to activate and deactivate /CS to the SD Card. If this is found to be a compatibility issue, this would be the only way to go about things. Though I would like to also have the driver work the current way when it doesn't detect the presence of an external MCU.
The initialization sequence gets completed and seems more stable than what's in the current driver, but I cannot get it to read data yet (even at low clock speeds, still returns only 0xFF).
Can you post or link-to the code you changed?
You should remove the dummy bytes for one. From what I remember, one of the tricks involved the way the response of a command is waited for, so be careful with that code, if you change it.

BTW, in case it becomes necessary to change the name of the device and driver
(so that it is unique), I guess you could use anything, but what about "SPI2PSD" which makes the SD less noticeable, if that is a concern, or maybe "PSPI2SD" ... but that gets suggestive of PSP :D (the P, standing for PlayStation (2)), or "P2SPI2SD" or "SPIP2SD", or some other combination. It would be good to decide on a unique name, else it may become a bit problematic in the future.


EDIT: And I guess I was totally sleeping when writing the above. Instead I meant: "PSIO2SD", "SIOP2SD", "SIO2PSD", etc.
 
Last edited:
So perhaps we can offload bit reversal and crc. But every feature has to be programmed, and I'm a little sceptical about the 1 day time it takes to program a uC.
Initially the only feature is to switch between Memory Card and SD of course. But the goal is to have a board that can do they key feature (switching SD/MC) and have the option to do every other feature we can imagine yet. The first idea was a board with the option to assamble two different MCUs, a big and a small one. But since they're so cheap and the structure of a smaller one is still the same (code can be easily ported), it's obsolete.

Does this MCU supports reprogramming (in this case by data read from SPI)?
I think so. There seems to be an official bootloader for this, already preinstalled! See Application Note AN2606. On the first page the feature is explained. On page 201 it's explained for the SMT32G07. The only downside is that the speed is limited to 8 MHz. I think we are not able to slow down the clock to 8 MHz, are we?
 
What about USB on the ST MCUs? (Although making USB drivers is a complex task AFAIK, that I have never done...)

The SPI clcok can be slowed down to at least 250kHz (used on controllers) - it is set as 48MHz / a set value 1 - 0xFF, so the slowest is ~190kHz, and exactly 8MHz is supported.

Here is the SIO2 registers info, gathered by me: http://www.mediafire.com/file/ajenlldof0zgss1/IOP_SIO2_2020.05.28.txt/file

For SIO0, you can see http://problemkaputt.de/psx-spx.htm#serialportsio although I have some more info regarding it - like how to interrupt transfers by EE to send single bits only, but that is not reliable and not important to this project.
 
The other day i was thinking in something but im not sure if is posible to do it, the idea is to duplicate the transfer speeds by using 2 SIO2SD cards in some kind of "RAID0 mode" :rolleyes:

The first requirement is the PS2 hardware should be able to use the two SIO data channels simultaneously, so you can transfer double amount of data in the same cycle
The second requirement is the driver (software) needs to do some kind of "data interleaving" to organize the data into 2 storage devices

Yeah, is a bit crazy, lol, and im not even sure if is posible to do it, but the point of this is with the actual driver @Maximus32 is achieving a bit over 1.2MB/s... and most probably the speed is going to be a big bigger after the optimizations he mentioned... lets say 1.7MB/s ? (dunno, im just throwing a reasonable number)
Yesterday i was taking a read at this thread https://www.psx-place.com/threads/max-theoretically-and-practical-ps2-transfer-speed-with-opl.21975/
By now it seems the SIO2SD is going to be close to beat USB, but if you duplicate that speed with the idea of RAID0 this is going to be very close to the speed of the optical drive, right ?
 
  • Like
Reactions: TnA
I don't think that is possible, because AFAIK only one SIO2 'channel' (port) can be active at a given time. You can't start transfers on two ports at the same time.

But if I remember correctly, in some cases the SIO2 SD card speed would reach 1.5MB/s, which depends on the SD Card a lot.
"The maximum read transfer rate (measured on 8 512-byte blocks) is ~ 1300kB/s (with CRC calculation) and 1600kB/s (no CRC) and significantly depends on the SD card used (lower speeds were observed with some SD card models). " - from the psx-scene.com thread.
"sz 00004000 1558 kB/s" - test by Maximus32 on psx-scene.com.
https://ia801500.us.archive.org/21/items/psx-scene-processed-archive/part0293.html#T157485P1
 
What about USB on the ST MCUs? (Although making USB drivers is a complex task AFAIK, that I have never done...)
The MCU does not have an USB connection. There are many ST MCUs supporting USB. I don't know why, but they only support SPI up to 18 MHz, some 24 MHz, but this is a little bit to tight for my taste.
I agree, we shouldn't write an USB driver, it is too complex. But for what we will need USB? Data can be transfered directly to the SD card with every card reader. For debugging there is UART and the special debugging connection.

but for example the https://www.microchip.com/wwwproducts/en/PIC32MX220F032B has USB and is around the same price (50MHz though), so that should be considered two.
What about SPI speed if the PIC32MX220F032B? I couldn't find out.
 
  • Like
Reactions: TnA
I was thinking of some USB connection for developers to use the SIO2 port for debugging the IOP... but of course this is too much to add only for that. Of course a UART would be much easier to use, the only downside being that it requires an external adapter. Yeah, - I should drop the idea for USB for now.

What about SPI speed if the PIC32MX220F032B? I couldn't find out.
25MHz.

BTW, I have been reading the (my) spi2sio driver code... there are some odd things there :D For example the writing seems to be done differently from the reading. I think it should be possible to use the same code as that for reading, for writing, but I am not sure if this will improve performance. However the writing code seems safer. The reading code (readSdUData()) might enter an infinite loop, if at any point over the transfer the /ACK line goes inactive (though this should never happen, and changing this will make reads slower).

@Maximus32 Can you determine which cards don't work and why so we can hopefully make the driver compatible?
I see what could be my second mistake and first unintentional - I don't send CMD 0 multiple times in a loop, but only once, unlike this: https://github.com/Krasutski/sdcard_spi_driver/blob/master/spi_sdcard_driver.c#L185 But I think that was fixed in the version of the driver you have.
So I would suggest changing the driver code only at the first command and making it sent in a loop, the same number of times as in the reference driver. I don't see any other significant differences. If you do, please list them here.
One other difference is that ACMD 41 and CMD 1 don't have timeouts in my code, so some timeout (number of retries) better be added, to prevent waiting indefinitely.
Or could the cause all along have been that the PS2 MC driver sends commands to the SD Card, which get it in some undetermined state and because I am sending the reset command CMD0 only once, it didn't manage to reset cards in that state?

EDIT: I checked the SD Card commands list - possible candidates for command to be used to exit (disable) the /CS (and enable PS2<->MCU communication) are:
- CMD13 - asks card for status reg. arg. is unused
- CMD58 READ_OCR - arg. is unused
- CMD59 CRC_ON_OFF - only one bit of the arg is used.
Could use a sequence of two commands too.

For the command to start communication, some command that has no effect on PS2 MC should be used, though that is not absolutely necessary.
A workaround could be to simply send first some command which to make sure that a PS2 (or PS1) MC is not connected and then if so, send command to MCU to start card I/O.
This should be enough to prevent problems if a user decides to swap the adapter with a PS2 MC for example.
Note that the bits order is reversed for the SD card, so MC commands don't appear to it with the same values.

Regarding MG, and MC commands:
Thread by TnA: https://ia801500.us.archive.org/21/items/psx-scene-processed-archive/part0293.html#T157491P1
MC commands: https://ia801500.us.archive.org/21/items/psx-scene-processed-archive/part0269.html#T120052P1
https://ia801500.us.archive.org/21/items/psx-scene-processed-archive/part0222.html#T101723P1

One way of identifying the MCU would be to make it respond to the PS1/PS2 MC packet start sequence in its own unique way.
 
Last edited:
I merged most pictures (except for one) into the "DIY-Builds"-Tab and renamed it to "Gallery"!
I kept @Maximus32's video and @Takeshi's video-link in the beginning.

I also added a new Tab regarding those Slims which are currently not compatible with it!


Awesome discussion/thread/project!
 
I have another crazy idea, the goal is to have a 2-in-1 card by "connecting together" a custom SIO2SD card and at the other side an official memory card (a bit customized)

The point is... inside the plastic shell of a memory card there seems to be room enought to have 2 circuit boards (im not so sure about this, but is very close)
In a official memory card there are components only in one side of the PCB... and the same happens in the SIO2SD card... so you can glue them together (with double side adhesive tape... like kapton tape)

The problem is the components are in the same side in both PCB, and this theoretical "2-in1" card needs to have only a row of "pins". So... i see 2 solutions to this problems
1) Redesign the SIO2SD card to move all the components to the other side, and remove the "pins"
2) Cut the "pins" of the official memory card and use wires to connect them together

Option 1 requires to use wires to solder the SIO2SD card to the official card, is a pita to redesign it at this point, and is not convenient, mostly because by doing it this way the official MC is going to be active at all times and the SIO2SD card would be the "slave" so is not posible to change the state of the official MC

Option 2 is better, the SIO2SD would be active all the time, and it allow to use a MCU in the SIO2SD card to do the switching of the official MC

I dont know the pinout or how to do this switching electrically, but i guess is not so hard (mostly a matter of switching the voltage line of the official MC), anyway... this kind of mod involves cutting the official MC like this
chU5I0K.jpg


After that cut is just a matter of glueing it to the SIO2SD card and solder a few wires :)




Edit:
Btw, i forgot to mention that this "expansion" to convert the SIO2SD card into a "2-in-1 card" could be something optional
There is no need to do it because the SIO2SD card could work standalone.... but incase someone wants to do it the SIO2SD circuit board could be ready for it
 
Last edited:
  • Like
Reactions: TnA
@Takeshi already had the "merging-idea" and works on it (once in a while) as well!
His approach is more sophisticated, using the MC's chips, tho'.

However... That is still "music of the future"!
 
@sandungas: This is the function we want to realize with the µC in the future. There will be a µC, the SD card and the components of the origininal MC. Everytime the µC is connected to the PS2 (here is the difference). Depending on commands from the PS2 the µC switches between the SD card and the MC components. That's the plan, but it will take a long time. First I will make a developement board for this which need more space but has also more features (for debugging). If it works, I will make a new and smaller desing.

Another goal of the µC can be the feature to disconnect the SD card from the power supply to reset the SD card. As we saw this could be usefull.
 
I bought a second hand transparent blue memory card to house the prototype when it arrives, concidered the red transparent one had floating around, but decided to keep it as a FMCB card for better differentiating between the 2
 
  • Like
Reactions: TnA
@sandungas: This is the function we want to realize with the µC in the future. There will be a µC, the SD card and the components of the origininal MC. Everytime the µC is connected to the PS2 (here is the difference). Depending on commands from the PS2 the µC switches between the SD card and the MC components. That's the plan, but it will take a long time. First I will make a developement board for this which need more space but has also more features (for debugging). If it works, I will make a new and smaller desing.

Another goal of the µC can be the feature to disconnect the SD card from the power supply to reset the SD card. As we saw this could be usefull.
I imagined it from the previous talks, but you mean only using one PCB, right ?
My suggestion was the cheap way by glueing the two PCB's to each other, maybe something temporal for the first prototypes
Actually... i guess it can be made in this first prototypes you are building just with a switch (operated manually), as @Fin9ersMcGee suggested
If an original ps2 memory card was retrofited with an SD card slot and a switch to to change between the 2, FMCB could be used before switching to SD?
The keyword here is "retrofited", lol, incase of glueing together both cards the "retrofit" involves to cut the MC and to solder a few wires
I think this is the only way to do it with the first prototypes of the SIO2SD card


Edit: or the other way around, cutting the SIO2SD card
 
Last edited:
Nevertheless it doesn't relieve you from building a new PCB with a µC for switching automatically. And if you design a board for this job, you can include the other things too.
Of course, if you are content with a manual switch, this might be a practicable way. But then I think it's more suitable to exchange the MC and SIO2SD ore use only one MC and the right port for the SD card.
 
Well, I've quickly realised that the memory card I purchased to gut and fill with the prototype board will be kinda going to waste, the ps2 memory card pcb i mean, so I might have a little go at adding an sd slot to that and some kind of switch to keep memory card original feature.
 
  • Like
Reactions: TnA
@Maximus32
That is the whole problem with SIO2 - we have no separate control of the /CS(/SS) line - it is activated *only* over each byte and if I am not mistaken, then deactivated for a short while and then activated over the next. One way to work-around that would be a fast external MCU which we could send commands to activate and deactivate /CS to the SD Card. If this is found to be a compatibility issue, this would be the only way to go about things. Though I would like to also have the driver work the current way when it doesn't detect the presence of an external MCU.

Can you post or link-to the code you changed?
You should remove the dummy bytes for one. From what I remember, one of the tricks involved the way the response of a command is waited for, so be careful with that code, if you change it.
I see. I'm now ignoring all read/write commands when the library deselects the card. That seems to make it work. I've restarted the sio2sd driver from scratch to make it more simple and hopefully more stable. Making it fast will come later, and then your code will be a great example of that. The restarted driver code is here:
https://gitlab.com/ps2max/ps2sdk/-/tree/master-ps2max/iop/memorycard/sio2sd_bd

It basically connects 3 separate libraries together:
BDM -> SD driver from Krasutski -> SIO2MAN.

The driver itself has almost no extra code. The result seems stable and also works on SLIM ps2. The SD driver from Krasutski seems unable to detect the correct size of the SD card, so that needs to be looked at (I've fixed it at 16GiB now). SIO2MAN is obviously much slower than the custom code @wisi has written, so expect around 100KB/s.

The ELF file for testing can be downloaded here:
https://gitlab.com/ps2max/testing/test_bdm/-/jobs/584717826/artifacts/browse

Please report your SD card, your ps2 type (fat/slim/scph-xxx) and your result.

I'm using a Samsung EVO 16GiB uSD card. It works on both FAT (SCPH-50004) and SLIM (SCPH-90006, FMCB compatible).
 
The SD driver from Krasutski seems unable to detect the correct size of the SD card
Might be because the data in the structure returned by the card is in big-endian.

I don't get why you decided to switch to the code from Krasutski, when it does almost exactly the same thing as "my" code (which is also based on other code), rather than switching between the two, where differences exist and this way pin-pointing the cause of the problems. ;) Guess the way you choose is faster to make.

The result seems stable and also works on SLIM ps2
I don't remember well, if I ever got a successful result on a DECKARD PS2, but one of the few reasons may be the speed setting I am using... DECKARD has some functions that intercept the speed setting AFAIR. Another reason may be some 'mistake' I have made in the order/values I set registers to, or some feature I am using (like paused transfer) not working on the PPC-IOP SIO2 (or unuspported by DECKARD).
 
I don't get why you decided to switch to the code from Krasutski, when it does almost exactly the same thing as "my" code (which is also based on other code), rather than switching between the two, where differences exist and this way pin-pointing the cause of the problems. ;) Guess the way you choose is faster to make.
I want the SD code to be completely separated from the SPI code. The interface between the SD and SPI code should be very simple, like 1 read/write function. This should make both parts (SD and SPI) of the driver simpler to understand, change and improve.
I switched becouse I was having too much difficulty separating the interfaces in the existing driver and I couldn't find the original source that you used. If you can find it I'll try to switch back? But I want 0 ps2 specific lines of code in the SD part of the driver. It should work on for instance arduino and ps2 without any changes. Perhaps the driver needs to be ENDIAN aware and isn't, but then we could send a PR to Krasutski if that's needed. Why maintain a complex piece of code, when so many other people are already doing it?

Currently the driver has clear separation like so:
sio2sd.png

It's now easy to switch to another SD-to-SPI driver. Or experiment with different speeds in the single sendCmd function. sendCmd and SIO2MAN probably need to be merged back into 1 fast function as you did though. But the interface to the SD driver should remain the exact same.

I don't remember well, if I ever got a successful result on a DECKARD PS2, but one of the few reasons may be the speed setting I am using... DECKARD has some functions that intercept the speed setting AFAIR. Another reason may be some 'mistake' I have made in the order/values I set registers to, or some feature I am using (like paused transfer) not working on the PPC-IOP SIO2 (or unuspported by DECKARD).
We've always thought SLIM would not work, so I'm already very happy it works at this slow speed. We'll see what happens when we increase the speeds.
 
Small update:
After each test the SD card needed to be re-inserted. Somehow the second test run always failed. To solve this I'm now flushing (reading) 512 bytes. This seems to fix that issue:
Code:
    /* Try to flush out any previous commands */
    for (i=0; i<512; i++)
        sendCmd(&byte, NULL, 1, 0, PORT_NR);
I'm not sure why this is needed though, and if 512bytes is too much or too little. But I guess it doesn't hurt also. Is there a better way to do this?
 
  • Like
Reactions: TnA

Similar threads

Back
Top