Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20711 Discussions

Nintendo DS Passthrough

Altera_Forum
Honored Contributor II
1,481 Views

Hiya, I'm trying to build a simple Nintendo DS card passthrough (also known as a "PassMe") -- basically use the FPGA as a man in the middle between the DS and DS card communication. 

 

I've written some Verilog code which simply reroutes the signals from DS CARD0 to DS CARD1, and back. 

 

The first 8 clock cycles is the command which is sent to a Nintendo DS card, after which the direction is switched and the card responds with data. 

The rom select (RCS) signal will go low when a new transfer is started. 

 

module main( CLOCK_50, DSCARD0_RCS, DSCARD0_ECS, DSCARD0_RES, DSCARD0_CLK, DSCARD0_DAT, DSCARD1_RCS, DSCARD1_ECS, DSCARD1_RES, DSCARD1_CLK, DSCARD1_DAT ); input CLOCK_50; input DSCARD0_RCS; input DSCARD0_ECS; input DSCARD0_RES; input DSCARD0_CLK; inout DSCARD0_DAT; output DSCARD1_RCS; output DSCARD1_ECS; output DSCARD1_RES; output DSCARD1_CLK; inout DSCARD1_DAT; assign DSCARD1_RCS = DSCARD0_RCS; assign DSCARD1_ECS = DSCARD0_ECS; assign DSCARD1_RES = DSCARD0_RES; assign DSCARD1_CLK = DSCARD0_CLK; reg IsCommand; reg CommandCounter; assign DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz; assign DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz; assign DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz; assign DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz; assign DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz; assign DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz; // assign DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz; // assign DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz; // assign DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz; // assign DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz; // assign DSCARD0_DAT = DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand? DSCARD1_DAT : 1'bz; // assign DSCARD1_DAT = DSCARD0_RES & ~DSCARD0_RCS & IsCommand? DSCARD0_DAT : 1'bz; always @(posedge DSCARD0_CLK or posedge DSCARD0_RCS) begin if (DSCARD0_RCS) begin CommandCounter <= 8'h0; IsCommand <= 1'b1; end else if (CommandCounter == 8'h7) IsCommand <= 1'b0; else CommandCounter <= CommandCounter + 8'h1; end endmodule  

 

I have a problem which makes card communication unstable when adding more assign DSCARD0/1_DAT[x] = ...; lines.  

Right now I'm connecting DAT[3] through DAT[7] directly to a real DS card, and DAT[0] through DAT[2] are connected to the FPGA, which are indirectly connected to the real DS card. 

 

With only DAT[0], DAT[1] and DAT[2] rerouted through the FPGA, the DS will still accept the card, and communication is stable 

 

Uncommenting the lines for DAT[3], DAT[4] and DAT[5] and connecting these signals indirectly to the DS card makes the communication more and more unstable. And I can't figure out why. 

 

Could someone shed some light on why this is? 

 

Thanks in advance.
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
748 Views

i'm not a Verilog guy but it doesn't look like you register card logic which could cause problems like this. how fast does the DS data run?

0 Kudos
Altera_Forum
Honored Contributor II
748 Views

you specify  

inout [7:0] DSCARD0_DAT; 

as an 8 bit bidir signal 

you correctly used assignments for that, but only for 6 bit [5:0] and no assignment for bit 6 and 7  

so you can combine these lines as 

 

assign DSCARD0_DAT[7:0] = (DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand ) ? DSCARD1_DAT[7:0] : 8'bzzzzzzzz; 

assign DSCARD1_DAT[7:0] = (DSCARD0_RES & ~DSCARD0_RCS & IsCommand ) ? DSCARD0_DAT[7:0] : 8'bzzzzzzzz; 

 

your problem no starts here where you try to switch the direction from card0 to card1 and vice versa with a registered signal. this is some kind of an asynchron dataloop, hard to dig down the problem. 

 

i have no information about how hard the timing must be in this application but if possible try to write a fully synchronus design and pipe some of the signals that the or clock synchron to each other.
0 Kudos
Altera_Forum
Honored Contributor II
748 Views

 

--- Quote Start ---  

i'm not a Verilog guy but it doesn't look like you register card logic which could cause problems like this. how fast does the DS data run? 

--- Quote End ---  

 

 

What do you mean with I don't register card logic? 

The DS clock runs at approx 6.7 MHz. 

 

 

 

--- Quote Start ---  

you specify  

inout [7:0] DSCARD0_DAT; 

as an 8 bit bidir signal 

you correctly used assignments for that, but only for 6 bit [5:0] and no assignment for bit 6 and 7  

so you can combine these lines as 

 

assign DSCARD0_DAT[7:0] = (DSCARD0_RES & ~DSCARD0_RCS & ~IsCommand ) ? DSCARD1_DAT[7:0] : 8'bzzzzzzzz; 

assign DSCARD1_DAT[7:0] = (DSCARD0_RES & ~DSCARD0_RCS & IsCommand ) ? DSCARD0_DAT[7:0] : 8'bzzzzzzzz; 

 

your problem no starts here where you try to switch the direction from card0 to card1 and vice versa with a registered signal. this is some kind of an asynchron dataloop, hard to dig down the problem. 

 

i have no information about how hard the timing must be in this application but if possible try to write a fully synchronus design and pipe some of the signals that the or clock synchron to each other. 

--- Quote End ---  

 

 

Yeah the reason for the seperate DSCARDx_DAT[] lines is that I was testing the signals one-by-one, while leaving 6 and 7 directly connected between CARD0 and CARD1. 

 

What do you mean the problem is with the registered signal? Could you explain this some more? 

 

How would a fully synchronous design look like? 

 

Thanks in advance
0 Kudos
Reply