DigitalInOut speed (interfacing an N64 Controller..)

28 Jul 2010

Hey all,

It's been a while since I did any work with the mbed. It's nice to see the progress you've all made! It's good to be back :)

I am trying to interface an N64 controller to the mbed. For those of you who are unfamilliar, the controller uses a single wire interface to communicate with the system. For starters, to request data for the controller 0x01 is sent to the controller and the response is sent back. This is where I seem to be having trouble.

The bits are sent in the following way:

And the sequence I am trying to send is:

The code I have come up with is the following:

#include "mbed.h"
#define HI 1
#define LO 0

DigitalInOut data(p14);
DigitalOut trigger(p28);            // Output pin for scope tirgger.

void send_byte(unsigned char byte);

int main() {

    data.mode(OpenDrain);           // Set pin to open-drain for N64 Controller.

    while (1) {
        wait_us(10000);
        send_byte(0);
    }
}

void send_byte(unsigned char byte) {
    char i;
    data.output();
    
    trigger=1;      // Scope trigger

    for (i=0; i<8; i++) {
        if (byte & 128>>i) {
            data.write(LO);
            wait_us(1);
            data.write(HI);
            wait_us(3);
        } else {
            data.write(LO);
            wait_us(3);
            data.write(HI);
            wait_us(1);
        }
    }
/* Send Stop Bit */
    data.write(LO);
    wait_us(1);
    data.write(HI);
    wait_us(3);

    trigger=0;
}


The problem I am having (I guess) is that the Digital IO is not fast enough to keep up.. The 1us width is 1.45us according to my scope, and the 3us width is 3.45us. I am unsure how to better optimize the code. The waveform is also somewhat jittery. I've seen this done with a 20MHz ATMEL chip, so the mbed should have no trouble doing it.. Can anyone suggest where to go from here?

More information about the N64 controller interface can be found here: http://www.mixdown.ca/n64dev/

30 Jul 2010

Well it turns out that the wait_us function was the problem, its just not stable and accurate enough for short wait times. As a workaround, I used a NOP loop to eat some time. I can get a response from the controller just fine. The problem now, it seems, is that DigitalInOut can't read fast enough. *Sigh*

The controller sends the response within 3us and lasts 128us. By the looks of it, the read() totally misses it.