1 //-------------------------------------------------------------------
3 // PLAYSTATION CONTROLLER(DUALSHOCK TYPE) INTERFACE TOP
7 // Copyright(c) 2003 - 2004 Katsumi Degawa , All rights reserved
11 // This program is freeware for non-commercial use.
12 // An author does no guarantee about this program.
13 // You can use this under your own risk.
15 // 2003.10.30 It is optimized for the FPGA game.
16 // It was made an analog mode fixation.(Dualshock)
19 //-------------------------------------------------------------------
20 //--------- SIMULATION ----------------------------------------------
21 //`define SIMULATION_1
28 //-------------------------------------------------------------------
31 `include "src/mc_conf.v"
35 I_CLK250K, // MAIN CLK 250KHz
37 O_psCLK, // psCLK CLK OUT
41 O_RXD_1, // RX DATA 1 (8bit)
42 O_RXD_2, // RX DATA 2 (8bit)
43 O_RXD_3, // RX DATA 3 (8bit)
44 O_RXD_4, // RX DATA 4 (8bit)
45 O_RXD_5, // RX DATA 5 (8bit)
46 O_RXD_6, // RX DATA 6 (8bit)
50 I_VIB_SW, // Vibration SW VIB_SW[0] Small Moter OFF 0:ON 1:
51 // VIB_SW[1] Bic Moter OFF 0:ON 1(Dualshook Only)
52 I_VIB_DAT // Vibration(Bic Moter)Data 8'H00-8'HFF (Dualshook Only)
56 input I_CLK250K,I_RSTn;
58 input I_MODE_SW,I_MODE_EN;
87 .I_TYPE(W_type), // DEGITAL PAD 0: ANALOG PAD 1:
89 .O_SCAN_SEQ_PLS(W_scan_seq_pls),
96 .O_byte_cnt(W_byte_cnt),
108 .I_BYTE_CNT(W_byte_cnt),
109 .I_MODE({I_CONF_SW,~I_MODE_EN,I_MODE_SW}),
111 .I_VIB_DAT(I_VIB_DAT),
112 .I_RXD_DAT(W_RXD_DAT),
113 .O_TXD_DAT(W_TXD_DAT),
115 .O_CONF_ENT(W_conf_ent)
124 .I_BYTE_CNT(W_byte_cnt),
129 .O_TXD_DAT(W_TXD_DAT),
131 .O_CONF_ENT(W_conf_ent)
143 .I_TXD_DAT(W_TXD_DAT),
154 .O_RXD_DAT(W_RXD_DAT)
158 //---------- RXD DATA DEC ----------------------------------------
167 always@(posedge W_scan_seq_pls)
168 W_rxd_mask <= ~W_conf_ent;
170 always@(negedge W_RXWT)
174 3: O_RXD_1 <= W_RXD_DAT;
175 4: O_RXD_2 <= W_RXD_DAT;
176 5: O_RXD_3 <= W_RXD_DAT;
177 6: O_RXD_4 <= W_RXD_DAT;
178 7: O_RXD_5 <= W_RXD_DAT;
179 8: O_RXD_6 <= W_RXD_DAT;
187 module txd_commnd_EZ(
203 input [3:0]I_BYTE_CNT;
206 input [7:0]I_VIB_DAT;
207 input [7:0]I_RXD_DAT;
208 output [7:0]O_TXD_DAT;
214 assign O_TYPE = 1'b1;
215 assign O_CONF_ENT = 1'b0;
216 always@(posedge I_CLK or negedge I_RSTn)
223 0:O_TXD_DAT <= 8'h01;
224 1:O_TXD_DAT <= 8'h42;
226 if(I_VIB_SW) O_TXD_DAT <= 8'h40;
227 else O_TXD_DAT <= 8'h00;
230 if(I_VIB_SW) O_TXD_DAT <= 8'h01;
231 else O_TXD_DAT <= 8'h00;
233 default: O_TXD_DAT <= 8'h00;
257 input [3:0]I_BYTE_CNT;
260 input [7:0]I_VIB_DAT;
261 input [7:0]I_RXD_DAT;
262 output [7:0]O_TXD_DAT;
273 assign O_TYPE = pad_id;
274 assign O_CONF_ENT = conf_entry;
276 always@(posedge I_CLK or negedge I_RSTn)
278 if(! I_RSTn) pad_id <= 1'b0;
280 if(I_BYTE_CNT==2)begin
281 case(I_RXD_DAT) //------ GET TYPE(Byte_SEQ)
282 8'h23: pad_id <= 1'b1;
283 8'h41: pad_id <= 1'b0;
284 8'h53: pad_id <= 1'b1;
285 8'h73: pad_id <= 1'b1;
286 8'hE3: pad_id <= 1'b1;
287 8'hF3: pad_id <= 1'b1;
288 default: pad_id <= 1'b0;
294 always@(posedge I_CLK or negedge I_RSTn)
304 //---------- nomal mode --------------------------------------------------------
305 //----------------- read_data_and_vibrate_ex 01,42,00,WW,PP(,00,00,00,00)
306 // --,ID,SS,XX,XX(,XX,XX,XX,XX)
309 0:O_TXD_DAT <= 8'h01;
310 1:O_TXD_DAT <= 8'h42;
313 if(I_VIB_SW[0]) O_TXD_DAT <= 8'h01;
314 else O_TXD_DAT <= 8'h00;
317 if(I_VIB_SW[0]|I_VIB_SW[1]) O_TXD_DAT <= 8'h40;
318 else O_TXD_DAT <= 8'h00;
323 if(I_VIB_SW[1]) O_TXD_DAT <= I_VIB_DAT;
324 else O_TXD_DAT <= 8'h00;
327 if(I_VIB_SW[0]|I_VIB_SW[1]) O_TXD_DAT <= 8'h01;
328 else O_TXD_DAT <= 8'h00;
342 default: O_TXD_DAT <= 8'h00;
345 //---------- confg mode --------------------------------------------------------
348 //-------- config_mode_enter (43): 01,43,00,01,00(,00 x 4 or XX x 16)
349 // --,ID,SS,XX,XX(,XX x 4 or XX x 16)
356 1:O_TXD_DAT <= 8'h43;
357 3:O_TXD_DAT <= 8'h01;
370 default:O_TXD_DAT <= 8'h00;
373 //-------- set_mode_and_lock (44): 01,44,00,XX,YY,00,00,00,00
377 0:O_TXD_DAT <= 8'h01;
378 1:O_TXD_DAT <= 8'h44;
381 if(I_RXD_DAT == 8'hF3)begin
390 3:O_TXD_DAT <= 8'h01;
393 if(pad_id==0 && conf_done==1'b1)begin
401 if(pad_id==1 && conf_done==1'b1)begin
406 default:O_TXD_DAT <= 8'h00;
409 //-------- query_model_and_mode (45): 01,45,00,5A,5A,5A,5A,5A,5A
410 // FF,F3,5A,TT,02,MM,VV,01,00
414 0:O_TXD_DAT <= 8'h01;
415 1:O_TXD_DAT <= 8'h45;
418 conf_done <= (I_RXD_DAT == 8'hF3)? 1'b0:1'b1;
422 if(I_RXD_DAT==8'h01 || I_RXD_DAT==8'h03) pad_status <= 1;
423 if(pad_id==0 && conf_done==1'b1)begin
431 if(pad_id==1 && conf_done==1'b1)begin
436 default:O_TXD_DAT <= 8'h00;
439 //-------- set_mode_and_lock (44): 01,44,00,XX,YY,00,00,00,00
440 // --,F3,5A,00,00,00,00,00,00
443 0:O_TXD_DAT <= 8'h01;
444 1:O_TXD_DAT <= 8'h44;
445 3:O_TXD_DAT <= 8'h01;
446 4:O_TXD_DAT <= 8'h03;
451 default:O_TXD_DAT <= 8'h00;
455 //-------- vibration_enable (4D): 01,4D,00,00,01,FF,FF,FF,FF
456 // --,F3,5A,XX,YY,FF,FF,FF,FF
459 0:O_TXD_DAT <= 8'h01;
460 1:O_TXD_DAT <= 8'h4D;
461 2,3:O_TXD_DAT <= 8'h00;
462 4:O_TXD_DAT <= 8'h01;
467 default:O_TXD_DAT <= 8'hFF;
470 //-------- config_mode_exit (43): 01,43,00,00,00,00,00,00,00
471 // --,F3,5A,00,00,00,00,00,00
474 0:O_TXD_DAT <= 8'h01;
475 1:O_TXD_DAT <= 8'h43;
476 2,3:O_TXD_DAT <= 8'h00;
483 default:O_TXD_DAT <= 8'h00;
513 parameter Timer_size = `Timer_siz;
517 output O_SCAN_SEQ_PLS;
524 output [3:0]O_byte_cnt;
526 output [Timer_size-1:0]Timer;
527 reg [Timer_size-1:0]Timer;
537 always@(posedge I_CLK or negedge I_RSTn)
539 if(! I_RSTn) Timer <= 0;
540 else Timer <= Timer+1;
543 always@(posedge I_CLK or negedge I_RSTn)
548 if(Timer == 0) O_SCAN_SEQ_PLS <= 1;
549 else O_SCAN_SEQ_PLS <= 0;
553 always@(posedge I_CLK or negedge I_RSTn)
577 always@(posedge I_CLK or negedge I_RSTn)
582 if(O_SCAN_SEQ_PLS == 1)
584 else if((I_TYPE == 0)&&(Timer == 158))
586 else if((I_TYPE == 1)&&(Timer == 286))
591 always@(posedge I_CLK or negedge I_RSTn)
596 if( O_SCAN_SEQ_PLS == 1)
599 if( Timer[4:0] == 5'b11111)begin
600 if(I_TYPE == 0 && O_byte_cnt == 5)
601 O_byte_cnt <= O_byte_cnt;
602 else if(I_TYPE == 1 && O_byte_cnt == 9)
603 O_byte_cnt <= O_byte_cnt;
605 O_byte_cnt <= O_byte_cnt+1;
611 assign O_psCLK = psCLK_gate | I_CLK | psSEL;
612 assign O_psSEL = psSEL;
613 assign O_RXWT = ~psSEL&RXWT;
614 assign O_TXSET = ~psSEL&TXSET;
615 assign O_TXWT = ~psSEL&TXWT;
616 assign O_TXEN = ~psSEL&(~psCLK_gate);
630 input I_CLK,I_RSTn,I_WT;
632 output [7:0]O_RXD_DAT;
636 always@(posedge I_CLK or negedge I_RSTn)
637 if(! I_RSTn) sp <= 1;
638 else sp <= { I_psRXD, sp[7:1]};
639 always@(posedge I_WT or negedge I_RSTn)
640 if(! I_RSTn) O_RXD_DAT <= 1;
641 else O_RXD_DAT <= sp;
658 input [7:0]I_TXD_DAT;
663 always@(negedge I_CLK or negedge I_RSTn)
675 ps <= {1'b1, ps[7:1]};