Author Topic: Saturn Controller Protocol MK80117 and Emulation  (Read 3579 times)

Offline RDC

  • SmallMember
  • **
  • Posts: 12
Saturn Controller Protocol MK80117 and Emulation
« on: March 15, 2013, 10:44:55 pm »
After tinkering around with the standard 6 button Saturn pads, MK-80116 and MK-80100. http://forums.modretro.com/viewtopic.php?f=34&t=11328

I figured I'd give the 3D (Nights) Controller a look see. This is based on the reader understanding Binary, specifically 8-bits ( or 1 Byte) or at the very least being able to count to 15 (4 bits) which if you can't do, Google it up, it's fun, you'll learn something and you can then appreciate that old joke, "There are 10 kinds of people that understand Binary, those that do, and those that don't. ;)

Now, the 3D Controller is by far different from the protocol used on the standard 6 buttons pads. Those only use 6 lines for communication, 2 Select bits and 4 Data, while the 3D Controller uses 7 lines.

The connector pinout is the same, looking into the end of the controller's connector, beveled side up.

Code: [Select]
/-----------\
| 987654321 |
|___________|

1 - 5v (Power to Controller)
2 - D1 (Data 1)
3 - D0 (Data 0)
4 - Request or REQ (Select 1, also known as TR)
5 - Select or SEL (Select 0, also known as TH)
6 - Acknowledge or ACK (also known as TL)
7 - D3 (Data 3)
8 - D2 (Data 2)
9  - Ground

NOTE* All 4 Data and the TR, TH, TL lines are pulled up to 5v with 100k Resistors inside the controller.

So here we see the data that's sent when the 3D Controller has the switch in the 'Digital' position.



Then here it is with the switch in the 'Analog' position.



The 4 Data lines still do the same thing, which is send 4 bits of Data at once. This is half of a Byte, which is 8 bits, so the 4 bits of Data here is called a 'nibble'. But the 3 T lines on the 3D controller differs in how that Data is sent.

The TH line acts like a 'Select', when it's pulled Lo then that controller is the one that's about to be queried for Data.

The TR line is a 'Request' from the Saturn for Data to be sent from the controller. When it changes states that's when it's Requesting Data to be sent, so from Hi to Lo is a Request, as is going from Lo to Hi.

The TL line is an 'Acknowledge' that the Data is ready for the Saturn to read it. This line 'follows' the TR 'Request' line, so when TR goes from Hi to Lo, after the Data is ready to be read, then the TL line also goes from Hi to Lo, or vice-versa depending on where you're starting from.

The 6 button pads only used 2 Bytes of Data, which were derived from the 4 states that the TR (S1) and TL (S0) lines could be put into. The 3D controller does this a little differently. The first Byte of Data sent is for both the ID for the type of controller, Digital, Analog, etc., and also the number of Bytes needed for the rest of the Data.

The first Byte sent goes like this.

First the SEL line is pulled Lo (yellow arrow down) This means the Saturn is getting ready to ask for Data from that device.
Second the REQ line goes Lo (green arrow down) This is the Saturn asking for Data from the controller.
Third the ACK line goes Lo (blue arrow down) This is the controller Acknowledging that the Data, 0000 for Digital controller in this case, is ready for the Saturn to read from D3~D0.
Fourth the REQ line goes Hi (green arrow up) This is the Saturn again requesting Data from the controller.
Fifth the ACK line goes Hi (blue arrow up) This is the controller again Acknowledging that the Data is ready, but this time it is 0010, which means 2 Bytes for the remaining Data.

This is how that first Byte looks on the Logic Analyzer.



Now, following those same steps, when the controller is in the 'Analog' mode, the first Byte is then 0001-0110, which is 0001 for Analog, then 0110 for 6 Bytes of Data.



Like the 6 button pads, my test setup used the PIC16F1516, PicKit 3, Saleae Logic Analyzer and 16x2 LCD screen.



Close up of the screen in Digital mode.



..Analog mode..



..and no 3D controller connected.



Another just awful video of this one working also - http://s50.beta.photobucket.com/user/RDCXBG/media/Saturn%203D/PICT7342_zpsb60e1511.mp4.html

I'll post the code up for this one later on once I go back thru it all as I want to give it a bit of an overhaul.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Now, Emulating the 3D controller. That is, making the Saturn 'think' you have a 3D controller connected, when it fact, it's just a  PIC, which is in this case again, the 16F1516. When using an external Crystal like I did here, this thing has just enough I/O (Input/Output) pins to pull this off.

This is also not 100% complete yet either. I do have both Digital and Analog modes working, but I don't have them setup so I can just flip a switch and go back and forth between them yet.

The buttons at the top are, from left to right, L, R, X, Y, Z, Start, A, C, B, D-pad R, L, D and U. The Stick is just from an old 360 controller. The original 3D controller uses a Hall Sensor type of Stick, which uses magnets, sensors and an OpAmp to do pretty much the exact same thing that a POT style Stick does.



This is the Data being sent between the PIC and the Saturn, which looks a lot like the pic above from the Data capture from the 3D controller in the Analog mode, but that was the idear. ;)



This is just the Digital portion of the code.

Code: [Select]
/*******************************************************************************
SEGA SATURN 3D CONTROLLER EMULATOR

PIC16F1516
EXTERNAL OSC @ 16MHz
5v POWER FROM SATURN

RDC 2013
*******************************************************************************/

char SPID, DATA_SIZE;

char DATA1_1, DATA1_2;
char DATA2_1, DATA2_2;
char DATA3_1, DATA3_2;

#define TH_SEL RA3_bit                   // Configure as Input
#define TR_REQ RA4_bit                   // Configure as Input
#define TL_ACK RA5_bit                   // Configure as Output

// Initialize the PIC
void INIT() {
ANSELA = 0b00000011;                     // AN0 and AN1 Analog to X and Y Axis
ANSELB = 0b00000000;                     // All AN are Digital
ANSELC = 0b00000000;                     // All AN are Digital
TRISA = 0b00011111;                      // PORTA
TRISB = 0b11111111;                      // PORTB, pins 6 and 7 also for ICSP
TRISC = 0b11110000;                      // PORTC
TRISE = 0b00001000;                      // PORTE, only 1 pin, RE3
TL_ACK = 1;
}


void main() {

   INIT();
     
  SPID = 0b00000000;
  DATA_SIZE = 0b00000010;

///// DIGITAL:

/////  Set Initial Button DATA for power up

    DATA1_1 = 0b11111111;                 // DATA1_1
    DATA1_2 = 0b11111111;                 // DATA1_2
    DATA2_1 = 0b11111111;                 // DATA2_1
    DATA2_2 = 0b11111111;                 // DATA2_2
    DATA3_1 = 0b00000000;                 // DATA3_1
    DATA3_2 = 0b00000001;                 // DATA3_2

  delay_ms(500);   // Wait for the Saturn to start up (takes around 1.5s)

  while(1) {

///// START COMMS WITH SATURN

    while(TH_SEL == 1) {}   // Wait for the Saturn to select controller
    delay_us(40);

    while (TR_REQ == 1 && TH_SEL == 0) {}  // Wait for Saturn to request SPID
    PORTC = SPID;           // SPID  0000 = Digital  // 0001 = Analog
    TL_ACK = 0;             // Here is the data
     
    while (TR_REQ == 0 && TH_SEL == 0) {}  // Wait for Saturn to request Data Size
    PORTC = DATA_SIZE;      // DATA_SIZE  0010 = 2 Bytes, 0110 = 6 Bytes
    TL_ACK = 1;             // Here is the data
     
///// START FIRST BYTE
   
    while (TR_REQ == 1 && TH_SEL == 0) {}  // Wait for Saturn to request first half of Data1
    PORTC = DATA1_1;        // DR, DL, DD, DU
    TL_ACK = 0;             // Here is the data
     
    while (TR_REQ == 0 && TH_SEL == 0) {}  // Wait for Saturn to request second half of Data1
    PORTC = DATA1_2;        // ST, A, C, B
    TL_ACK = 1;             // Here is the data
   
///// END FIRST BYTE

///// START SECOND BYTE

    while (TR_REQ == 1 && TH_SEL == 0) {}  // Wait for Saturn to request first half of Data2
    PORTC = DATA2_1;        // R, X, Y, Z
    TL_ACK = 0;             // Here is the data

    while (TR_REQ == 0 && TH_SEL == 0) {}  // Wait for Saturn to request second half of Data2
    PORTC = DATA2_2;        // L, 1, 1, 1
    TL_ACK = 1;             // Here is the data

///// END SECOND BYTE

///// START THIRD BYTE, END OF DATA

    while (TR_REQ == 1 && TH_SEL == 0) {}  // Wait for Saturn to request first half End
    PORTC = DATA3_1;        // 0000
    TL_ACK = 0;             // Here is the data

    while (TR_REQ == 0 && TH_SEL == 0) {}  // Wait for Saturn to request second half of End
    PORTC = DATA3_2;        // 0001
    TL_ACK = 1;             // Here is the data

///// END THIRD BYTE

    while(TH_SEL == 0) {}   // Wait for the Saturn to deselect controller
   
///// END COMMS WITH SATURN
   
/////  Get Current Button DATA (in less than 15ms, less than 300us if an Action Replay is used)

    DATA1_1 = PORTC >> 4;                 // DATA1_1
    DATA1_2 = PORTB;                      // DATA1_2
    DATA2_1 = PORTB >> 4;                 // DATA2_1
    DATA2_2 = (PORTA << 1) + 7;           // DATA2_2
    DATA3_1 = 0b00000000;                 // DATA3_1
    DATA3_2 = 0b00000001;                 // DATA3_2

  }
}


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

If anyone can, or would like to, build and test out the 3D controller Emulator, here are the hex and schematic files.

http://rapidshare.com/files/1982581024/Saturn%203D%20Controller%20EMU.rar

The PIC needs to be a 16F1516, and it requires the PicKit 3 to flash it.

X1 is a 16MHz Crystal, the C1 and C2 values depend on the Crystal used, but 20pf is a 'ballpark' value if you don't know what value it requires.

C3 is a DeCoupling Capacitor and is optional but recommended, anything from 0.01uf to 1uf will do.

S1 is a SPDT switch for the Digital/Analog modes.

Any 10k POT style stick can be used for the X-Axis and Y-Axis. (['m sure this needs some adjusting in code)

J1 is the controller cable that plugs into the Saturn. 1- 5v, 2- D1, 3- D0, 4- REQ, 5- SEL, 6- ACK, 7- D3, 8- D2, 9- GND

J2 is the programming header for the PIC. 1- VPP, 2- VDD, 3- VSS, 4- DAT, 5- CLK

R1 thru R21 can be anything from 10k to 100k in value.
« Last Edit: January 31, 2016, 11:55:00 pm by RDC »
Screwing up is one of the best learning tools, so long as the only thing you're not learning is how to screw up.

Offline Lawrence

  • Runs the place
  • Administrator
  • ThrobbingMember
  • *****
  • Posts: 3331
    • NFGgames
Re: Saturn Controller Protocol MK80117 and Emulation
« Reply #1 on: March 16, 2013, 07:54:40 am »
What a brilliant project!  Well done.  =D

Offline RDC

  • SmallMember
  • **
  • Posts: 12
Re: Saturn Controller Protocol MK80117 and Emulation
« Reply #2 on: March 16, 2013, 11:57:40 am »
Thanks. I need to do some more testing with it, mainly to tweak the Analog bit of the code, since the Hall stick in the 3D controller is capable of hitting it's min/max values in every direction, where a POT style stick can't because it's usually mechanically limited by the shell it's in.

Before that though I want to build it into some controller shell for testing, as trying to play Nights with it on the bread board like that is more of a challenge than the game itself. I'll probably build one into a 360 shell at some point, as I can use my 36X board for it.  http://s50.beta.photobucket.com/user/RDCXBG/library/36X%20Controller%20PCB
Screwing up is one of the best learning tools, so long as the only thing you're not learning is how to screw up.

Offline fluxcore

  • SmallMember
  • **
  • Posts: 2
Re: Saturn Controller Protocol MK80117 and Emulation
« Reply #3 on: January 01, 2016, 09:54:04 am »
I 'recently' adapted some code for a PIC16F4550 (20MHz xtal) to emulate the 3d controller in digital mode (for arcade stick use) as per the information in this thread, and it works great - EXCEPT in the Action Replay menu. Which stinks, since it's the very first thing you encounter, and don't want to take it out often at all.

It seems like the Action Replay just stops polling the relevant data lines. I don't have an official 3d controller to use to confirm it works, but I've asked some other people and they claim it does.

I wonder if there's some extra part of the spec that's missing, but that seems hard to believe...

Offline RDC

  • SmallMember
  • **
  • Posts: 12
Re: Saturn Controller Protocol MK80117 and Emulation
« Reply #4 on: January 01, 2016, 12:19:52 pm »
"Rise from your grave"

It's been almost 2 years since I messed with any of this, but I never did any testing with an Action Replay (mainly as I don't have one) or really anything else at all with it after this. Only the Saturn and the controller and then the controller and a PIC, but there is nothing missing here in how that all worked. Everything that the Logic Analyzer saw is pretty much here, but again, not with an AR in the Saturn, so I couldn't even guess what might be going on there.

Provided that an official controller does work, maybe try a faster or slower INIT of your code as maybe something is just slightly askew there and hanging things up with the AR and detecting the controller. I could only take wild stabs in the dark like that without having one here and digging all of that back out and connecting it up to see what was really going on. That is, after testing it straight up with the controller to make sure that it does work. If I get the retro itch again and have $30 or so bucks not doing anything I'll pick up and AR and see what's going on there with the 3D controller.
« Last Edit: January 30, 2016, 01:33:00 am by RDC »
Screwing up is one of the best learning tools, so long as the only thing you're not learning is how to screw up.

Offline RDC

  • SmallMember
  • **
  • Posts: 12
Re: Saturn Controller Protocol MK80117 and Emulation
« Reply #5 on: January 30, 2016, 11:43:24 pm »
OK, for any others that are playing along here. I have an AR Plus now (v2.02) and it does work fine with the 3D controller in either the Digital or Analog modes, though the Analog nub does nothing.

I have observed that the AR is in part causing the 'issue' here. For whatever reason, it's only polling the controller for 14.25ms, with around 310us pauses in between, so it's polling much quicker, but the real issue is after this 14.25ms is up, it then drives the SEL line Hi and goes about it's business for ~2.5ms after that, then back to polling.



It does not wait for the current controller polling 'session' to finish before it does this, and that just screws the timing of everything all up as the code wasn't designed to handle that, so it just locks it all up.



I've edited the code now to also check on the state of the SEL line while waiting for the REQ line to change, so when the AR drives that SEL line Hi now the code will not hang up.

Code used to be..
Code: [Select]
while (TR_REQ == 1) {}

while (TR_REQ == 0) {}

..and all 4 instances of each in the Digital section (8 of each in the Analog section) were changed to..

Code: [Select]
while (TR_REQ == 1 && TH_SEL == 0) {}

while (TR_REQ == 0 && TH_SEL == 0) {}

It's not exactly how I'd want it to handle the issue, but so far it works and has been tested from power up, then into the console settings, to the AR menu and then to launching the game from there, so there are no more hang ups currently. More testing will need done, but for now this should correct the issue, and hopefully not cause any more.
Screwing up is one of the best learning tools, so long as the only thing you're not learning is how to screw up.

Offline Xabaras76

  • SmallMember
  • **
  • Posts: 3
Re: Saturn Controller Protocol MK80117 and Emulation
« Reply #6 on: April 21, 2017, 04:28:41 pm »
Hello to everyone,

I'm considering to build this controller emulator, but I think that the link to all the files is dead.

Is there any possibility to get those files again.?

Thank you so much in advance.!

Offline RDC

  • SmallMember
  • **
  • Posts: 12
Re: Saturn Controller Protocol MK80117 and Emulation
« Reply #7 on: April 22, 2017, 12:23:52 am »
Here you go - https://mega.nz/#!rk0WCKJL!Zg_CDYkPJIXGjWYMC_DIIhHs1j-bnyYgdq5Z5xdhLS0

If that link says you need the decryption key, it is - !Zg_CDYkPJIXGjWYMC_DIIhHs1j-bnyYgdq5Z5xdhLS0
Screwing up is one of the best learning tools, so long as the only thing you're not learning is how to screw up.

Offline Xabaras76

  • SmallMember
  • **
  • Posts: 3
Re: Saturn Controller Protocol MK80117 and Emulation
« Reply #8 on: April 22, 2017, 02:49:08 am »
Thank you so much.!!! :D
I've been looking for something like this for a long time.
It is strange but it is difficult to build a custom pad for Saturn .
I've found  some info in gamesx.com site...but I've read that the schematics there are not right.

And all the post regarding that scheme are quite old and all the pic loaded on Imageshack are no longer available.
And also I have found different port pinout betweek the scheme of Kashima(the one provided in gamesx site) and the one reported in gamesx.com Saturn controller page.

I will make a new scheme in Eagle so , maybe there will be a clear and corrected schematic.
I will test my scheme on my Saturn before post it here.

Thanks again for your precious help.!

I wish everybody a great day  :)