PAD Serial

Start a work log and update it occasionally with your projects progress
ackerman
Curious PSXDEV User
Curious PSXDEV User
Posts: 29
Joined: Aug 21, 2019

Post by ackerman » October 30th, 2022, 2:43 am

nocash wrote: October 29th, 2022, 4:15 am Or is there some hardware issue that prevents higher speeds? I am sure that could be fixed by adding some resistors or diodes in the console or in the cables.
Thank you. The maximum stable speed I have reached is 71680 bps, 8 KB/s.
I don't remember all the exact tests, but with pullup resistors, pulldown resistors, transistors on some of the problematic pins, the result was very bad. The best thing has been with direct wires and the same scheme as:

https://github.com/foobarflies/pianette

The tests have been done on 5 psx model 5002, 7002, 9002 and psone, all of them PAL.

Since I lose bits, the most perfect result so far, without data loss in transmission, is to use only 4 bits of 1 byte, as well as maximum 7 bits of 1 byte.
I would appreciate any help on the best cable to build, as well as protocol or even best suited MCU, but best suited to the current project, i.e. ultra low budget (arduino nano).
nocash wrote: October 29th, 2022, 4:15 am And why do you use a 10 seconds transfer delay??? If the (second?) controller disturbs the transfer, couldn't you just detect if it's disconnected, and then start without delay?
The option to detect disconnection of the controller has been implemented since the first serial port test, and can be seen in the initial menu, indicating to press the O button, instead of the X button. In the video test, out of laziness I sent the X command instead of O, and that's why the 10-second wait is displayed.
nocash wrote: October 29th, 2022, 4:15 am Uh, and what is that drawing with L1,L2,R1,R2 buttons about? I hope you don't put your data into that 4bit slot? You can simply transfer a continous bitstream (except the first byte; which is reserved for selecting whether the data goes to the joypad, the memory card, or to your cable).
The first speed tests, from 0 to 1, use a buffer of transistors or optocouplers associated with the side buttons, which are the easiest to solder, sending 4 bits. It was an initial proof of concept, which worked without a single failure, although excessively slow. This option would now be deprecated.

For speeds 0 - 3 , I encapsulate the data in SPI messages (0x01 0x42 xxx) in digital control mode.

For speeds 8 - 11 the same, but with analogue command mode (0x73).
Both options work without a single problem, but slowly, about 1920 bps. All these options work not only in real psx, but also in emulator with a usb controller converter. Let's say, that this option currently, I also have it deprecated.


The emulators do not implement custom SPI, so the development can only be tested on a real machine.

The 12 -32 speeds I use a custom SPI message, and that's where I get the 71680 bps.
The reads from the PADSIO port I'm syncing with every fps, i.e. 50 fps or 60 fps, and I'm working in the standard 250 Khz SPI mode, both on the PSX and ARDUINO side. I guess to get the 2Mbyte/s I should change the PADSIO speed on the PSX and raise the SPI speed on the ARDUINO from 500 Khz to 8 Mhz. I guess I should stop synchronizing with the video, and be in loop mode reading constantly from the PADSIO port, and when I finish reading everything, I should dump the video. Am I right?

Have you done any kind of test like this? Any help would be appreciated.

User avatar
nocash
PSX Aficionado
PSX Aficionado
Posts: 541
Joined: Nov 12, 2012
Contact:

Post by nocash » October 31st, 2022, 5:37 am

ackerman wrote: October 30th, 2022, 2:43 am Have you done any kind of test like this?
I've made this one, http://problemkaputt.de/psxspx-mods-noc ... upload.htm the transfer circuit is basically a 74HC541 driver and some wires; it's using parallel data transfer (7bit data + 1bit clock) and wired directly to PSX mainboard (or expansion port).

The cable is around 1.5 meters long, and the transfer speed is around 600-700 Kbyte/s (it might work faster on PSX side, but the PC parallel port can only send that much data per second). I would assume that the PSX serial/controller port can handle similar clock rates, which would be around 100 Kbytes/s for 1bit serial.
ackerman wrote: October 30th, 2022, 2:43 am I don't remember all the exact tests, but with pullup resistors, pulldown resistors, transistors on some of the problematic pins, the result was very bad.
Did you consider "signal reflection"? The old BNC ethernet cables did use BNC terminators at the end of the cable to avoid reflections (but that's been for very long cables with high MBit/s rates; I am not sure if that problem applies for shorter cables) (the reflection delay would be CableLength*2 vs SpeedOfLight).

If relections are causing problems: The SPI bus signals are all one-directional, so you could insert a diode or AND gate to enforce one-way signals and blocking reflections. For example, this should pass LOW levels in only one direction (and pull-up the signal when there's no LOW level):

Code: Select all

                      .--[1K]-- Vcc
             BAT 85   |
   Output ----|<|-----'-------- Input
How many controller(s) and memory card(s) do have connected during the transfer? And with which cable lengths?

Best would be to have only the USB adpator, with very short serial cable. Or additionally one joypad with the diode idea wired like this:

Code: Select all

          .---usb--------------------------------- pc
          |
   PSX ---'---diode------------------------------- joypad
The short wires in memory cards are hopefully not causing any problems, but better disconnect them to see if that helps.
ackerman wrote: October 30th, 2022, 2:43 am The 12 -32 speeds I use a custom SPI message, and that's where I get the 71680 bps.
The reads from the PADSIO port I'm syncing with every fps, i.e. 50 fps or 60 fps, and I'm working in the standard 250 Khz SPI mode, both on the PSX and ARDUINO side.
I guess I should stop synchronizing with the video, and be in loop mode reading constantly from the PADSIO port
The first byte is something other than 01h or 81h to make sure that controllers and memory cards won't respond to it?
The first byte should be send at 250 bit/s, and remaining bytes as fast as you can go.
Syncing the controller reads to vblank shouldn't cause problems... just make sure that you have interrupts disabled when transferring your custom data packets (via cpu SR register or via EnterCriticalSection).
Thereafer, the controller reads should happen once when you re-enable the interrupts (assuming that the controller reads are triggered on vblank interrupt).
ackerman wrote: October 30th, 2022, 2:43 am and raise the SPI speed on the ARDUINO from 500 Khz to 8 Mhz.
The SPI clock selection on the slave side (arduino) should be don't care because the clock comes from the master (from the PSX). Unless you mean something like enabling a "special high-speed-signal-filtering mode" (if such a thing should exist).
ackerman wrote: October 30th, 2022, 2:43 am Since I lose bits, the most perfect result so far, without data loss in transmission, is to use only 4 bits of 1 byte, as well as maximum 7 bits of 1 byte.
That shouldn't happen... which bits are getting lost? Is it something specific like 1st bit of each byte? And do you get "0" or "1" bits or randomly either one instead of the intended values?
It might be because some signal transitions aren't fast enough, or because controllers or memory cards are also trying to output some bits during the transfer.
Anyways, the clock bits are apparently never getting lost, or else the transfer would derail completely.

ackerman
Curious PSXDEV User
Curious PSXDEV User
Posts: 29
Joined: Aug 21, 2019

Post by ackerman » November 1st, 2022, 11:44 pm

nocash wrote: October 31st, 2022, 5:37 am Did you consider "signal reflection"? The old BNC ethernet cables did use BNC terminators at the end of the cable to avoid
Thank you very much for your help. I have not taken into account the reflection, I thought that working with 250 Khz, it would not influence much. When I started the project, I had very low speeds in mind (9600 bps). At home I have at hand the 1n4148 diodes and the schottky BAT43, so as soon as I can, I'll do a couple of tests with them and the pullup resistor.
nocash wrote: October 31st, 2022, 5:37 am How many controller(s) and memory card(s) do have connected during the transfer? And with which cable lengths?
I'm using an extension cable, I guess 1.5 meters, not soldered to the arduino pins, so it will also have an influence. As soon as I get my handset cable, without sacrificing a functional one, I will also test with the shortest possible cable.
I only have one control cable connected, which goes to the arduino, so that the other devices don't interfere. I don't have any cards or extra controllers added.

For the custom message, I'm sending 0x01 0x00. I can test that it doesn't send 0x01.
nocash wrote: October 31st, 2022, 5:37 am That shouldn't happen... which bits are getting lost? Is it something specific like 1st bit of each byte? And do you get "0" or "1" bits or randomly either one instead of the intended values?
I don't remember exactly all the tests I did, as they are 2 years old, but I remember that from 5 bytes onwards, random problems started to occur. As the digital command mode frames came in at 5 bytes, there were never any failures. Only in analogue mode and in custom messages, the failures appeared. By reducing the ACK time to 0 microseconds, the faults were reduced, but they still occurred. The most practical solution was to work with 4 bits, disregarding the upper 4 bits. Failures never occur with 4 bits. And by forcing up to 7 bits, bugs are minimised. The faults did not point to a pullup output, since it was random 0, 1 even if the bit was constant. The wire is obviously not correct, but I managed to circumvent the problem in a not very elegant way.

User avatar
nocash
PSX Aficionado
PSX Aficionado
Posts: 541
Joined: Nov 12, 2012
Contact:

Post by nocash » November 2nd, 2022, 4:18 am

Looking into the PSone service manual, the DATA and ACK inputs already have 1K pull-ups in there, so you won't need external pull-ups on those lines. And most of the signals have to 100pF capacitors wired to GND, that will probably conflict with higher clock rates. If you have an oscilloscope then you'll see at which speeds the capacitors are smearing the signals too much.

Interestingly, the schematic says that the CLK pin is bidirectional. Probably unimportant for you, I am just wondering if it's possible to switch the CLK direction with one of the PSX hardware registers.

Avoid 1n4148 diodes, those won't work well for fast switching 3V signals. BAT85 usually works fine. I've no idea if BAT43 is good or bad.
ackerman wrote: November 1st, 2022, 11:44 pm I'm using an extension cable, I guess 1.5 meters, not soldered to the arduino pins, so it will also have an influence. As soon as I get my handset cable, without sacrificing a functional one, I will also test with the shortest possible cable.
I only have one control cable connected, which goes to the arduino, so that the other devices don't interfere. I don't have any cards or extra controllers added.
That is... like this?

Code: Select all

   __________
  |          |
  |     card1|----
  |      joy1|--------- extension cable 1.5m ----- not soldered to arduino
  | PSX      ]
  |      joy2|--------- control cable ------------ goes to arduino
  |     card2|----
  |__________|          unknown? ----------------- joypad 1

                        unknown? ----------------- joypad 2

                        not connected ------------ cards

                        not connected ------------ extra controllers
I would remove the extension cable, especially if it isn't connected anywhere. And, if your transfer is starting automatically then it should work without joypads... but you mentioned pressing X or O to start the transfer, so you do have a joypad attached somewhere?

Btw. if you don't have spare disassembled controller connectors: It might be easier to plug DIY circuits into the memory card sockets.
ackerman wrote: November 1st, 2022, 11:44 pm For the custom message, I'm sending 0x01 0x00. I can test that it doesn't send 0x01.
I think that would be better. The five "don't use" values are 01h,02h,03h,04h,81h (which would conflict with joypads, multitaps, memcards).
ackerman wrote: November 1st, 2022, 11:44 pm I don't remember exactly all the tests I did, as they are 2 years old, but I remember that from 5 bytes onwards, random problems started to occur. As the digital command mode frames came in at 5 bytes, there were never any failures. Only in analogue mode and in custom messages, the failures appeared. By reducing the ACK time to 0 microseconds, the faults were reduced, but they still occurred. The most practical solution was to work with 4 bits, disregarding the upper 4 bits. Failures never occur with 4 bits. And by forcing up to 7 bits, bugs are minimised. The faults did not point to a pullup output, since it was random 0, 1 even if the bit was constant. The wire is obviously not correct, but I managed to circumvent the problem in a not very elegant way.
Okay, If it would be an UART then I would say wrong bitrate, but that can't happen for SPI with CLK signal.
So it might be reflections. Or the capacitors in the console. Or a long cable without shielding.

ACK time 0 microseconds means ACK is not used at all? That ACK stuff is of course not needed for SPI transfers, but it might be useful in some cases...

I would send one ACK at the begin of the transfer (to indicate that the packet was received via USB and that it's ready for transfer to PSX), and then send the packet bytes without any ACKs.

Other ACK idea - don't do this unless you are 100% sure that you have reached the fastest possible CLK rate - when using a 2bit parallel SPI transfer with carefully timed MIPS code, then one could send one byte through the DATA line (with hardware shift register), and another byte through ACK line (with software bit shifting) to double the transfer rate.

Btw. where do you boot your PSX code from? From CDROM, and then using the controller cable to upload newer EXE files for testing the updated transfer code?

ackerman
Curious PSXDEV User
Curious PSXDEV User
Posts: 29
Joined: Aug 21, 2019

Post by ackerman » November 3rd, 2022, 3:50 am

nocash wrote: November 2nd, 2022, 4:18 am That is... like this?
Thank you very much. My current configuration only uses command port 2.

Code: Select all

   __________
  |          |
  |     card1|
  |      joy1|
  | PSX      ]
  |      joy2|--------- cable extension pad 1.5m ----- not soldered to arduino
  |     card2|
  |__________|         
nocash wrote: November 2nd, 2022, 4:18 am Btw. where do you boot your PSX code from? From CDROM, and then using the controller cable to upload newer EXE files for testing the updated transfer code?
In the Arduino SelectPADSpeed procedure, putting the arduino in SetModePAD digital controller mode, I send it the keystrokes above,... and the X button to select the speed:

Code: Select all

 gbConfig.h

 //Select speed 24 .. 32
 #define use_lib_bps_2425
 //#define use_lib_bps_2829
 //#define use_lib_bps_3233
 
 //flag or not flag speed
 #define use_lib_flag
Once selected, the entire data buffer is automatically sent.

The padsioup is the psx loader. For now, being in testing it is set to load at 0x80190000, to be compatible with the hitserial hitmen loader. It can be put on an iso and burned to cdrom, as well as changing the loading start position.

The bin2hex (windows) is a parser that allows to convert the PSEXE into an Arduino buffer with header and with the possibility to choose the speed and direction of loading. If nothing is chosen, it will use the PSEXE's own address.
In addition to PSEXE from psyq, it loads PSEXE from the blade libraries without any problem.


I leave the code if you want to try it. It's for testing, so it's not of great quality. I have not yet changed the 0x01 code in the first byte.
padsio.zip
You do not have the required permissions to view the files attached to this post.

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 4 guests