• Login
  • Register
  • Dolphin Forums
  • Home
  • FAQ
  • Download
  • Wiki
  • Code


Dolphin, the GameCube and Wii emulator - Forums › Dolphin Emulator Discussion and Support › Development Discussion v
« Previous 1 ... 14 15 16 17 18 ... 116 Next »

Wii Serial Interface: Dolphin doesn't match real hardware?
View New Posts | View Today's Posts

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Thread Modes
Wii Serial Interface: Dolphin doesn't match real hardware?
11-24-2018, 03:57 AM (This post was last modified: 11-24-2018, 04:03 AM by Shonumi.)
#1
Shonumi Offline
Linux User/Tester
**********
Administrators
Posts: 6,502
Threads: 55
Joined: Dec 2011
So, I'm dabbling with some Wii homebrew. The goal is to probe any JoyBus devices via the Serial Interface (SI). To start off, I simply want to send the ID command (0x00) and read the response to get the device ID. I'm using the latest DevkitPro and DevkitPPC. Here is the source code:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

static void *xfb = NULL;
static GXRModeObj *rmode = NULL;

vu32* const si_reg = (u32*)0xCD006400;
vu32* const si_buf = (u32*)0xCD006480;

//Generates 32-bit value that can be written to SICOMCSR to start a transfer on a given channel
u32 generate_com_csr(u32 channel, u32 in_len, u32 out_len)
{
    u32 com_csr = 0;

    in_len &= 0x7F;
    out_len &= 0x7F;
    channel &= 0x3;
        
    //Channel
    com_csr |= (channel << 25);

    //Channel Enable
    com_csr |= (1 << 24);

    //Output Length
    com_csr |= (out_len << 16);

    //Input Length
    com_csr |= (in_len << 8);

    //Command Enable
    com_csr |= (1 << 7);

    //Channel 2?
    com_csr |= (channel << 1);

    //Callback Enable
    com_csr |= (0 << 6);

    //TSTART
    com_csr |= 1;

    return com_csr;
}

//Sends the JOYBUS command 0x00 to the given channel
//Used to find out the device ID (written to SI buffer)
void ping_ID(u32 channel)
{
    //Clear SI buffer
    for(int x = 0; x < 0x80; x++) { si_buf[x] = 0; }
    
    //Setup JOYBUS command 0x00
    si_buf[0] = 0x00;

    //Write to SICOMCSR to start transfer, wait for any pending transfers first
    while(si_reg[13] & 0x1) { }
    si_reg[13] = generate_com_csr(channel, 4, 2);

    //Wait for next SICOMCSR transfer to finish
    while(si_reg[13] & 0x1) { }    
}

//---------------------------------------------------------------------------------
int main(int argc, char **argv) {
//---------------------------------------------------------------------------------

    // Initialise the video system
    VIDEO_Init();

    // This function initialises the attached controllers
    WPAD_Init();

    // Obtain the preferred video mode from the system
    // This will correspond to the settings in the Wii menu
    rmode = VIDEO_GetPreferredMode(NULL);

    // Allocate memory for the display in the uncached region
    xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));

    // Initialise the console, required for printf
    console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);

    // Set up the video registers with the chosen mode
    VIDEO_Configure(rmode);

    // Tell the video hardware where our display memory is
    VIDEO_SetNextFramebuffer(xfb);

    // Make the display visible
    VIDEO_SetBlack(FALSE);

    // Flush the video register changes to the hardware
    VIDEO_Flush();

    // Wait for Video setup to complete
    VIDEO_WaitVSync();
    if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();

    u32 loop = 0;
    u32 vcount = 0;

    while(1) {
        vcount++;
    
        if(vcount == 60)
        {
            ping_ID(0);
            u32 id_1 = si_buf[0];

            ping_ID(1);
            u32 id_2 = si_buf[0];

            ping_ID(2);
            u32 id_3 = si_buf[0];

            ping_ID(3);
            u32 id_4 = si_buf[0];

            printf("%x\n", loop++);
            printf("ID 1 -> 0x%x\n", id_1);
            printf("ID 2 -> 0x%x\n", id_2);
            printf("ID 3 -> 0x%x\n", id_3);
            printf("ID 4 -> 0x%x\n\n", id_4);

            vcount = 0;
        }        

        // Call WPAD_ScanPads each loop, this reads the latest controller states
        WPAD_ScanPads();

        // WPAD_ButtonsDown tells us which buttons were pressed in this loop
        // this is a "one shot" state which will not fire again until the button has been released
        u32 pressed = WPAD_ButtonsDown(0);

        // We return to the launcher application via exit
        if ( pressed & WPAD_BUTTON_HOME ) exit(0);

        // Wait for the next frame
        VIDEO_WaitVSync();
    }

    return 0;
}

Attached below are the .dol and .elf files as well (in the ZIP file). I believe this is the (mostly) correct way of doing things. Clear the SI I/O buffer, write the command to the buffer, then initiate a transfer via SICOMCSR. I only had Dolphin's source code + Yet Another Gamecube Doc to go off of, and I haven't touched the GC/Wii Serial Interface in years (not since 2014 I guess).

Anyway, the latest master builds of Dolphin run the code as expected. Every second, it prints out something like...

Code:
ID 1 -> 0x09000000
ID 2 -> 0x8
ID 3 -> 0x8
ID 4 -> 0x8

This is normally what I'd want/expect to see. 0x09000000 represents a standard GC controller attached to a given controller port, and 0x8 is Dolphin's default response an unconnected device. I can change the attached device in Dolphin to something like the GC Keyboard or Steering Wheel or Dancing Mat, and it updates the ID accordingly.

Unfortunately, running this on real hardware (Nintendo Wii RVL-001) gives different results. I loaded up the .dol through the Homebrew menu and got results like this (Standard 1st-party GC Controller attached to Port 1):

Code:
ID 1 -> 0x20000300
ID 2 -> 0x0
ID 3 -> 0x0
ID 4 -> 0x0

So, my question is, does anyone have any idea what's going on? The zeroes for the rest of the IDs are not concerning, but the first one is totally unexpected.


Attached Files
.zip   joybus_probe.zip (Size: 761.77 KB / Downloads: 97)
Website Find
Reply
11-24-2018, 07:04 AM
#2
DJBarry004 Offline
Don't even bother...
*******
Posts: 2,456
Threads: 33
Joined: Sep 2013
I "played" with your program and catched some more values (in Dolphin).

If you select the GC adapter for Wii U or the Steering Wheel they will both print 0x8000000. Dance Mat will print 0x9000930 and the DK Bongos will print the same value as Standard Controller.

The GC Keyboard prints 0x8200000.

For some reason, if I enable the DK Bongos in ports 2, 3 and 4, it will keep printing the "disconnected" value (0x8).
Rig 1: Windows 10 Home | AMD A6-1450 @ 600/1000/1400 MHz | AMD Radeon HD Graphics 8250 | 4GB RAM | HP Pavilion TouchSmart 11.

Rig 2: Windows 10 Pro | Intel Core i7-2640M @ 780/2800/3500 MHz | Intel HD 3000 Mobile | 8GB RAM | Dell Latitude 6320.
Find
Reply
11-24-2018, 07:21 AM (This post was last modified: 11-24-2018, 07:22 AM by Shonumi.)
#3
Shonumi Offline
Linux User/Tester
**********
Administrators
Posts: 6,502
Threads: 55
Joined: Dec 2011
Yeah, those are the expected values when using Dolphin. Those are the JoyBus IDs for each device. The thing is that a real Wii was messing up. Should have reported 0x9000000 for a Gamecube controller, but instead on my Wii it reported 0x200000300.

Anyway, I guess this might be due to something to do with the Homebrew Channel? My guess is that it's doing something before loading the .dol that changes how the Serial Interface works before executing the .dol. Maybe interrupt related, I dunno. I guess I should have run my .dol through the Homebrew Channel in Dolphin to compare results accurately, my bad.

I think I may have tried going too low-level, accessing the individual hardware registers instead of using libogc's built-in SI functions. I couldn't figure out how they worked until I found the source code for some GBA Link Cable dumper. Now I've modified my source code, and I can get the JoyBus IDs in both Dolphin and my Wii. There are still some minor differences, but the JoyBus ID is what I need for now, so I'm satisfied with the results.
Website Find
Reply
« Next Oldest | Next Newest »


  • View a Printable Version
  • Subscribe to this thread
Forum Jump:


Users browsing this thread: 1 Guest(s)



Powered By MyBB | Theme by Fragma

Linear Mode
Threaded Mode