/* USB Host Controller for DE2-115 ISP1362 clk 50MHz HID_joypad support BUFFALO BSGP801 USB Pad SuperSmartJoy SFC Pad to USB SANWA JY-PSUAD1 PlayStation Pad to USB 2015/11/07 Ver.1.0 */ %d HcControl 0x01 // HcControl %d HcFmItv 0x0D // HcFmInterval %d HcRhA 0x12 // HcRhDescriptorA %d HcRhB 0x13 // HcRhDescriptorB %d HcRhStatus 0x14 // HcRhStatus %d HcRhP1 0x15 // HcRhPortStatus[1] %d HcRhP2 0x16 // HcRhPortStatus[2] %d HcIntDone 0x17 // HcINTLPTDDoneMap %d HcIntSkip 0x18 // HcINTLPTDSkipMap %d HcIntLast 0x19 // HcINTLLastPTD %d HcATLDone 0x1B // HcATLPTDDoneMap %d HcATLSkip 0x1C // HcATLPTDSkipMap %d HcATLLast 0x1D // HcATLLastPTD %d HcHWCfg 0x20 // HcHardwareConfiguration %d HcTransferCnt 0x22 // HcTransferCounter %d HcUpInt 0x24 // HcμPInterrupt %d HcUpIntEnable 0x25 // HcμPInterruptEnable %d HcChipID 0x27 // HcChipID %d HcScratch 0x28 // HcScratch %d HcBufStatus 0x2C // HcBufferStatus %d HcDirAddrLen 0x32 // HcDirectAddressLength %d HcInt_Port 0x43 // HcINTLBufferPort %d HcATL_Port 0x44 // HcATLBufferPort %d HcDirAddr_Port 0x45 // HcDirectAddressData %d HcATLThrsCnt 0x51 // HcATLPTDDoneThresholdCount %d HcATLTimeOut 0x52 // HcATLPTDDoneThresholdTimeOut %d HcIntBlkSize 0x53 // HcINTLBlkSize %d HcATLBlkSize 0x54 // HcATLBlkSize %d HcReset 0xA9 // HcSoftwareReset %d TOKEN_SETUP 0b00 %d TOKEN_OUT 0b01 %d TOKEN_IN 0b10 circuit ISP1362_ctrl { output WRn, RDn, A<2>, Dout<16>; reg_ws WRn_reg, RDn_reg; reg_wr A_reg<2>, Dout_reg<16>; input Din<16>; reg_wr Din_reg<16>; output button<16>; reg_wr button_reg<16>; output dbg<8>; reg_wr dbg_reg<8>; output dbgh<16>; reg_wr dbgh_reg<16>; reg_ws reset; sel notused; reg_wr reg_no<8>, data2write16<16>, data2write32<32>, r16_ret<16>, r32_ret<32>; reg_wr acc_wcount<11>; // 約40us reg_wr port2speed; reg_wr idProduct<16>; reg_wr mbuf_1<16>; mem cbuf[8]<16>; mem rbuf[16]<16>; reg_wr rw_wait<4>; reg_wr assign_address_ret<16>; reg_wr set_address_ret<16>; reg_wr send_control_ret<16>; rega uni_req[2]<16>; reg_wr hid_req<16>; // make_ptd reg_wr token<2>, ep, max<8>, tog, addr<8>, port<2>; // get_control reg_wr control_type<8>; reg_wr get_control_ret<16>; // new_make_ptd reg_wr total<8>; reg_wr set_config_ret<16>; // make_int_ptd reg_wr freq<8>; reg_wr send_int_ret<16>; reg_wr breg_4<16>, breg_5<16>, breg_6<16>; // stage_name test { task do(); } stage_name main { task do(); } stage_name USB_HC_CMD_WRITE { task do(Dout_reg); } stage_name USB_HC_DATA_WRITE { task do(Dout_reg); } stage_name USB_HC_DATA_READ { task do(); } stage_name w16 { task do(reg_no, data2write16); } stage_name r16 { task do(reg_no); } stage_name w32 { task do(reg_no, data2write32); } stage_name r32 { task do(reg_no); } stage_name reset_usb { task do(); } stage_name hid { task do(); } stage_name set_operational { task do(); } stage_name enable_port { task do(); } stage_name erase_all { task do(); } stage_name assign_address { task do(); } stage_name set_address { task do(); } stage_name make_ptd { task do(token, ep, max, tog, addr, port); } stage_name array_app_uni { task do(uni_req_0, uni_req_1); } stage_name send_control { task do(); } stage_name write_atl { task do(); } stage_name read_atl { task do(); } stage_name get_control { task do(control_type); } stage_name array_app_dev { task do(); } stage_name array_app_hid { task do(hid_req); } stage_name new_make_ptd { task do(token, ep, max, tog, addr, port, total); } stage_name set_config { task do(); } stage_name play_hid { task do(); } stage_name make_int_ptd { task do(token, ep, max, tog, addr, port, freq); } stage_name send_int { task do(); } stage_name write_int { task do(); } stage_name read_int { task do(); } par{ if(reset){ reset := 0; generate main.do(); // generate test.do(); } notused = 0; WRn = WRn_reg; RDn = RDn_reg; A = A_reg; Dout = Dout_reg; // for SNESPAD<12> : B,Y,Sl,St,Up,Dn,Le,Ri,A,X,L,R if(idProduct==0x2060){ // BUFFALO BSGP801 button_reg := 0x0 || breg_5<1> || breg_5<3> || breg_5<6> || breg_5<7> || ^breg_4<15> || breg_4<14> || ^breg_4<7> || breg_4<6> || breg_5<0> || breg_5<2> || breg_5<4> || breg_5<5>; } if(idProduct==0x0667){ // SFC Pad to USB SuperSmartJoy button_reg := 0x0 || breg_4<2> || breg_4<3> || breg_4<4> || breg_4<5> || ^breg_5<7> || breg_5<6> || ^rbuf[4]<15> || rbuf[4]<14> || breg_4<1> || breg_4<0> || breg_4<6> || breg_4<7>; } if(idProduct==0x3011){ // PlayStation Pad to USB SANWA JY-PSUAD1 button_reg := 0b00 || breg_6<11> || breg_6<9> || breg_6<4> || breg_6<6> || breg_6<12> || breg_6<13> || ^breg_5<15> || breg_5<14> || ^breg_5<7> || breg_5<6> || breg_6<5> || breg_6<7> || breg_6<8> || breg_6<10>; } if(idProduct==0x0000){ button_reg := 0x0000; } button = button_reg; dbg = dbg_reg; dbgh = dbgh_reg; } /* // スクラッチパッドテスト stage test { reg_wr rst_cnt<6>; state_name rst,st1,st2,st3,st4; first_state rst; state rst par{ rst_cnt++; if(/&rst_cnt) goto st1; } state st1 par{ generate r16.do(HcChipID); // ChipID 0x3630 goto st2; } state st2 if(^r16.do){ dbgh_reg := r16_ret; generate w16.do(HcScratch, 0x1234); goto st3; } state st3 if(^w16.do){ generate r16.do(HcScratch); goto st4; } state st4 if(^r16.do){ if(r16_ret==0x1234) dbg_reg := 0xAA; else dbg_reg := 0x99; finish; } } //32bitWRtest //候補レジスタ 0x6A 0x6C 0x0D 0x32 0x18 0x1C stage test { sel test_regno<8>; state_name st1,st2,st3; first_state st1; par{ test_regno = 0x1C; } state st1 par{ generate w32.do(test_regno, 0x12345678); goto st2; } state st2 if(^w32.do){ generate r32.do(test_regno); goto st3; } state st3 if(^r32.do){ if(r32_ret==0x12345678) dbg_reg := 0xAA; else dbg_reg := 0x99; dbgh_reg := r32_ret<15:0>; // dbgh_reg := r32_ret<31:16>; finish; } } */ stage main { reg_wr rst_cnt<6>; state_name rst,st1,st2,st3; first_state rst; state rst par{ rst_cnt++; if(/&rst_cnt) goto st1; } state st1 par{ generate w16.do(HcReset, 0x00F6); goto st2; } state st2 if(^w16.do){ generate reset_usb.do(); goto st3; } state st3 if(^reset_usb.do){ generate hid.do(); finish; } } /* A0: phase selection 0: data phase 1: command phase A1: bus selection 0: host (HC) 1: device (DC) */ stage USB_HC_CMD_WRITE { state_name st1,st2,st3,st4; first_state st1; state st1 par{ WRn_reg := 0; A_reg := 0b01; goto st2; } state st2 par{ WRn_reg := 1; goto st3; } state st3 par{ acc_wcount++; if(/&acc_wcount) goto st4; } state st4 par{ goto st1; finish; } } stage USB_HC_DATA_WRITE { state_name st1,st1w1,st1w2,st2,st3,st4; first_state st1; state st1 par{ WRn_reg := 0; A_reg := 0b00; goto st1w1; } state st1w1 goto st1w2; state st1w2 goto st2; state st2 par{ WRn_reg := 1; goto st3; } state st3 par{ acc_wcount++; if(/&acc_wcount) goto st4; } state st4 par{ goto st1; finish; } } stage USB_HC_DATA_READ { state_name st1,st2,st3,st4; first_state st1; state st1 par{ RDn_reg := 0; A_reg := 0b00; goto st2; } state st2 par{ RDn_reg := 1; Din_reg := Din; goto st3; } state st3 par{ acc_wcount++; if(/&acc_wcount) goto st4; } state st4 par{ goto st1; finish; } } stage w16 { state_name st1,st2,st3; first_state st1; state st1 par{ generate USB_HC_CMD_WRITE.do(0x00 || (reg_no | 0x80)); goto st2; } state st2 if(^USB_HC_CMD_WRITE.do){ generate USB_HC_DATA_WRITE.do(data2write16); goto st3; } state st3 if(^USB_HC_DATA_WRITE.do){ goto st1; finish; } } stage r16 { state_name st1,st2,st3; first_state st1; state st1 par{ generate USB_HC_CMD_WRITE.do(0x00 || reg_no); goto st2; } state st2 if(^USB_HC_CMD_WRITE.do){ generate USB_HC_DATA_READ.do(); goto st3; } state st3 if(^USB_HC_DATA_READ.do){ r16_ret := Din_reg; goto st1; finish; } } stage w32 { state_name st1,st2,st3,st4; first_state st1; state st1 par{ generate USB_HC_CMD_WRITE.do(0x00 || (reg_no | 0x80)); goto st2; } state st2 if(^USB_HC_CMD_WRITE.do){ generate USB_HC_DATA_WRITE.do(data2write32<15:0>); goto st3; } state st3 if(^USB_HC_DATA_WRITE.do){ generate USB_HC_DATA_WRITE.do(data2write32<31:16>); goto st4; } state st4 if(^USB_HC_DATA_WRITE.do){ goto st1; finish; } } stage r32 { reg_wr result_l<16>; state_name st1,st2,st3,st4; first_state st1; state st1 par{ generate USB_HC_CMD_WRITE.do(0x00 || reg_no); goto st2; } state st2 if(^USB_HC_CMD_WRITE.do){ generate USB_HC_DATA_READ.do(); goto st3; } state st3 if(^USB_HC_DATA_READ.do){ result_l := Din_reg; generate USB_HC_DATA_READ.do(); goto st4; } state st4 if(^USB_HC_DATA_READ.do){ r32_ret := Din_reg || result_l; goto st1; finish; } } stage reset_usb { state_name st1,st2,st3,st4; first_state st1; state st1 par{ generate w16.do(HcHWCfg, 0x302D); goto st2; } state st2 if(^w16.do){ generate w32.do(HcFmItv, 0x25002EDF); goto st3; } state st3 if(^w32.do){ generate w32.do(HcControl, 0x00000600); goto st4; } state st4 if(^w32.do){ goto st1; finish; } } stage hid { reg_wr port2; state_name st1,st2,st3,st4,st5,st6,st7,st8,st9,st10,st11,st12,st13,st14,st15,st16,st17, st20,st21,st23,st24,st50,st51,st52; first_state st1; if(notused) finish; state st1 par{ port2 := 0; idProduct := 0x0000; generate set_operational.do(); goto st2; } state st2 if(^set_operational.do){ generate enable_port.do(); goto st3; } state st3 if(^enable_port.do){ generate reset_usb.do(); goto st4; } state st4 if(^reset_usb.do){ generate erase_all.do(); goto st5; } state st5 if(^erase_all.do){ generate set_operational.do(); goto st6; } state st6 if(^set_operational.do){ generate enable_port.do(); goto st7; } state st7 if(^enable_port.do){ generate w16.do(HcControl, 0x06C0); goto st8; } state st8 if(^w16.do){ generate w16.do(HcUpInt, 0x01A9); goto st9; } state st9 if(^w16.do){ generate w16.do(HcBufStatus, 0x0000); goto st10; } state st10 if(^w16.do){ generate w32.do(HcATLSkip, 0xFFFFFFFE); goto st11; } state st11 if(^w32.do){ generate w32.do(HcATLLast, 0x00000001); goto st12; } state st12 if(^w32.do){ generate w16.do(HcATLBlkSize, 64); goto st13; } state st13 if(^w16.do){ generate w16.do(HcATLThrsCnt, 1); goto st14; } state st14 if(^w16.do){ generate w16.do(HcATLTimeOut, 200); goto st15; } state st15 if(^w16.do){ generate assign_address.do(); goto st16; } state st16 if(^assign_address.do){ generate w16.do(HcUpIntEnable, 0x0120); goto st17; } state st17 if(^w16.do){ if(assign_address_ret<0>) goto st20; else goto st1; } // port 2 active state st20 par{ // get_control(rbuf,2,'D',0,2) generate get_control.do('D'); goto st21; } state st21 if(^get_control.do){ // チェックポイントok //dbgh_reg := get_control_ret; // 0x0300 //dbg_reg++; if(get_control_ret==0x0300){ idProduct := rbuf[0x9]; goto st23; } else goto st1; } state st23 par{ // get_control(rbuf,2,'H',addr_info(2,'R','P',0),2); generate get_control.do('H'); goto st24; } state st24 if(^get_control.do){ // チェックポイント dbgh_reg := get_control_ret<11:8> || mbuf_1<11:0>; // 0x3X09 dbg_reg++; if(mbuf_1==0x0209) port2 := 1; // if(mbuf_1==0x0609) Keyboard if(mbuf_1==0x0409) port2 := 1; // if(mbuf_1==0x09ff) Launcher goto st50; } state st50 par{ if(port2){ // set_config(2,1) generate set_config.do(); goto st51; } else goto st1; } state st51 if(^set_config.do){ if(set_config_ret==0){ // play_mouse(2) generate play_hid.do(); } goto st52; } state st52 if(^play_hid.do){ goto st1; } } stage set_operational { state_name st1,st2,st3,st4; first_state st1; state st1 par{ generate w16.do(HcHWCfg, 0x302D); goto st2; } state st2 if(^w16.do){ generate w32.do(HcFmItv, 0x25002EDF); goto st3; } state st3 if(^w32.do){ generate w32.do(HcControl, 0x00000680); goto st4; } state st4 if(^w32.do){ goto st1; finish; } } stage enable_port { state_name st1,st2,st3,st4,st5,st6,st7,st8,st9; first_state st1; state st1 par{ generate w32.do(HcRhP1, 0x00000102); goto st2; } state st2 if(^w32.do){ generate w32.do(HcRhP2, 0x00000102); goto st3; } state st3 if(^w32.do){ generate w32.do(HcRhStatus, 0x00010000); goto st4; } state st4 if(^w32.do){ generate w32.do(HcRhA, 0x20000102); goto st5; } state st5 if(^w32.do){ generate w32.do(HcRhB, 0x00000000); goto st6; } state st6 if(^w32.do){ generate r32.do(HcRhP2); goto st7; } state st7 if(^r32.do){ if(r32_ret<0>){ // CurrentConnectStatus device connected // set_port_speed(2, 0); port2speed := 0; goto st8; } else goto st9; } state st8 par{ if(r32_ret<9>){ // LowSpeedDeviceAttached // set_port_speed(2, 1); port2speed := 1; } goto st9; } state st9 par{ goto st1; finish; } } stage erase_all { reg_wr ea_cnt<11>; // 2048 state_name st1,st2,st3,st4; first_state st1; state st1 par{ generate w32.do(HcDirAddrLen, 4096<<16); goto st2; } state st2 if(^w32.do){ generate USB_HC_CMD_WRITE.do(0x00 || (HcDirAddr_Port | 0x80)); ea_cnt := 0; goto st3; } state st3 if(^USB_HC_CMD_WRITE.do){ generate USB_HC_DATA_WRITE.do(0x0000); goto st4; } state st4 if(^USB_HC_DATA_WRITE.do){ ea_cnt++; if(/&ea_cnt){ goto st1; finish; } else goto st3; } } stage assign_address { reg_wr rhp2;//, rhp1; state_name st1,st2,st3,st4,st5; first_state st1; state st1 par{ // rhp1 := 0; // rhp2 := 0; generate r32.do(HcRhP1); goto st2; } state st2 if(^r32.do){ // rhp1 := r32_ret<0>; // 1ならポート1検出 generate r32.do(HcRhP2); goto st3; } state st3 if(^r32.do){ rhp2 := r32_ret<0>; // 1ならポート2検出 generate enable_port.do(); goto st4; } state st4 if(^enable_port.do){ // 第1チェックポイントok //dbgh_reg := 0x1234; //dbg_reg := 0b0000000 || rhp2; if(rhp2){ // set_address(0,2,2); ここのみ generate set_address.do(); goto st5; } else{ assign_address_ret := 0x0000; goto st1; finish; } } state st5 if(^set_address.do){ assign_address_ret := set_address_ret<11:0> || 0x1; // status goto st1; finish; } } // set_address(int old_addr, int new_addr, int port) // set_address(0,2,2); stage set_address { state_name st1,st2,st3,st4,st5,st6,st6a,st7,st8,st8a,st9,st10; first_state st1; state st1 par{ // new_addr=2 generate w16.do(HcUpInt, 0x0100); goto st2; } state st2 if(^w16.do){ generate r32.do(HcATLDone); goto st3; } state st3 if(^r32.do){ generate r32.do(HcATLDone); goto st4; } state st4 if(^r32.do){ // make_ptd(cbuf,SETUP,0,8,0,old_addr,port); generate make_ptd.do(TOKEN_SETUP, 0, 8, 0, 0, 2); goto st5; } state st5 if(^make_ptd.do){ // array_app(cbuf+4, uni_req, 4); generate array_app_uni.do(0x0500, 2); goto st6; } state st6 if(^array_app_uni.do){ generate send_control.do(); goto st6a; } state st6a if(^send_control.do){ //dbgh_reg := rbuf[0b0000000]; //dbg_reg++; if(send_control_ret==0){ set_address_ret := 0xF00 || rbuf[0x0]<15:12>; goto st9; } else{ set_address_ret := 0x000 || rbuf[0x0]<15:12>; if(rbuf[0x0]<15:12>==0) goto st7; else goto st9; } } // if(mycode==0) state st7 par{ // make_ptd(cbuf,IN,0,0,1,old_addr,port); generate make_ptd.do(TOKEN_IN, 0, 0, 1, 0, 2); goto st8; } state st8 if(^make_ptd.do){ generate send_control.do(); goto st8a; } state st8a if(^send_control.do){ if(send_control_ret==0){ set_address_ret := 0xF00 || rbuf[0x0]<15:12>; } else{ set_address_ret := 0x000 || rbuf[0x0]<15:12>; } goto st9; } state st9 par{ generate r32.do(HcATLDone); goto st10; } state st10 if(^r32.do){ goto st1; finish; } } // make_ptd(IN,0,8,toggle_cnt%2,addr,port); // make_ptd { task do(token, ep, max, tog, addr, port); } stage make_ptd { state_name st1,st2,st3,st4; first_state st1; state st1 par{ cbuf[0b000] := 0b0000 || 0b1 || tog || 0b0000000000; goto st2; } state st2 par{ // epは0 // max_size<8> cbuf[0b001] := 0b0000 || 0b0 || port2speed || 0b00 || max; goto st3; } state st3 par{ cbuf[0b010] := 0b0000 || token || 0b00 || max; goto st4; } state st4 par{ // addr<8> cbuf[0b011] := 0x00 || addr; goto st1; finish; } } // array_app(cbuf+4,uni_req,4); stage array_app_uni { state_name st1,st2,st3,st4; first_state st1; state st1 par{ cbuf[0b100] := uni_req_0; goto st2; } state st2 par{ cbuf[0b101] := uni_req_1; goto st3; } state st3 par{ cbuf[0b110] := 0x0000; goto st4; } state st4 par{ cbuf[0b111] := 0x0000; goto st1; finish; } } stage send_control { reg_wr timeout<4>, snd_cnt<16>, wp_count<5>; state_name st0,st1,st2,st3,st4,st5,st6,st7,st8,st9,st10; first_state st0; state st0 par{ timeout := 9; goto st1; } state st1 par{ snd_cnt := 50000; // write_atl(a_ptr, 8); generate write_atl.do(); goto st2; } state st2 if(^write_atl.do){ generate w16.do(HcUpInt, 0x0100); goto st3; } state st3 if(^w16.do){ generate r32.do(HcATLDone); goto st4; } state st4 if(^r32.do){ generate r32.do(HcATLDone); goto st5; } state st5 if(^r32.do){ generate w16.do(HcBufStatus, 0x0008); // ATL_Active goto st6; } state st6 if(^w16.do){ generate r16.do(HcUpInt); wp_count := 0; snd_cnt--; goto st7; } state st7 if(^r16.do){ wp_count++; if(/&wp_count){ // poll if((snd_cnt!=0) & (r16_ret<8>==0b0)){ // active_bit=1 goto st6; } else goto st8; } } state st8 par{ // 第2チェックポイント //dbgh_reg := 0b000||snd_cnt; //dbg_reg := 0b0000000||r16_ret<8>; // 1のはず generate w16.do(HcBufStatus, 0x0000); goto st9; } state st9 if(^w16.do){ // read_atl(r_ptr, 72); generate read_atl.do(); goto st10; } state st10 if(^read_atl.do){ timeout--; if((rbuf[0x0]<15:12>!=0) & (timeout!=0)){ goto st1; } else{ // rbuf[0x0]<15:12>は0、snd_cntは4700くらい? send_control_ret := snd_cnt; goto st0; finish; } } } stage write_atl { reg_wr wa_cnt<3>; state_name st1,st2,st2w,st3,st4; first_state st1; state st1 par{ generate w16.do(HcTransferCnt, 16); goto st2; } state st2 if(^w16.do){ generate USB_HC_CMD_WRITE.do(0x00||(HcATL_Port|0x80)); wa_cnt := 0; goto st2w; } state st2w if(^USB_HC_CMD_WRITE.do){ // 必要のようだ rw_wait++; if(/&rw_wait) goto st3; } state st3 par{ generate USB_HC_DATA_WRITE.do(cbuf[wa_cnt]); goto st4; } state st4 if(^USB_HC_DATA_WRITE.do){ wa_cnt++; if(wa_cnt==7){ goto st1; finish; } else goto st3; } } stage read_atl { reg_wr ra_cnt<4>; state_name st1,st2,st2w,st3,st4; first_state st1; state st1 par{ generate w16.do(HcTransferCnt, 32); goto st2; } state st2 if(^w16.do){ generate USB_HC_CMD_WRITE.do(0x00||HcATL_Port); ra_cnt := 0; goto st2w; } state st2w if(^USB_HC_CMD_WRITE.do){ // 必要のようだ rw_wait++; if(/&rw_wait) goto st3; } state st3 par{ generate USB_HC_DATA_READ.do(); goto st4; } state st4 if(^USB_HC_DATA_READ.do){ rbuf[ra_cnt] := Din_reg; ra_cnt++; if(ra_cnt==(16-1)){ goto st1; finish; } else goto st3; } } // get_control(rbuf, 2, 'D', 0, 2); // get_control(rbuf, 2, 'H', addr_info(2,'R','P',0), 2); // get_control(*rptr, addr, control_type, extra, port) stage get_control { reg_wr ccode<16>, toggle_cnt; reg_wr MaxSize<8>, DesSize<8>; state_name st1,st2,st3,st4,st5,st6,st7,st8,st9,st10,st11, st12,st13,st14,st15,st16,st17,st18,st19,st20,st21,st22; first_state st1; state st1 par{ toggle_cnt := 0b0; // make_ptd(cbuf,SETUP,0,8,0,addr,port); generate make_ptd.do(TOKEN_SETUP, 0, 8, 0, 2, 2); goto st2; } state st2 if(^make_ptd.do){ any{ control_type=='D' : generate array_app_dev.do(); // array_app(cbuf+4,dev_req,4); control_type=='H' : generate array_app_hid.do(0x2100); // array_app(cbuf+4,hid_req,4); } goto st3; } state st3 if(^(array_app_dev.do | array_app_hid.do)){ generate send_control.do(); goto st4; } state st4 if(^send_control.do){ if(send_control_ret==0){ get_control_ret := 0xF100; goto st1; finish; } else{ ccode := 0x0000; goto st5; } } state st5 par{ toggle_cnt := 0b1; // make_ptd(cbuf,IN,0,8,toggle_cnt%2,addr,port); generate make_ptd.do(TOKEN_IN, 0, 8, 1/*toggle_cnt*/, 2, 2); goto st6; } state st6 if(^make_ptd.do){ generate send_control.do(); goto st7; } state st7 if(^send_control.do){ if(rbuf[0x0]<15:12>==0x9){ ccode := 0x0000; } else{ ccode := 0x000 || rbuf[0x0]<15:12>; } goto st8; } state st8 par{ if(send_control_ret==0){ ccode := ccode | 0xF000; } DesSize := rbuf[0x4]<7:0>; if(control_type=='D'){ if(rbuf[0x7]<15:11>==0) MaxSize := 8; // 7以下 else MaxSize := rbuf[0x7]<15:8>; } goto st9; } state st9 par{ if(control_type=='H'){ if(rbuf[0x7]<15:11>==0) DesSize := 8; // 7以下 else DesSize := rbuf[0x7]<15:8>; } if(ccode==0){ // make_ptd(cbuf,OUT,0,0,toggle_cnt%2,addr,port); generate make_ptd.do(TOKEN_OUT, 0, 0, toggle_cnt, 2, 2); goto st10; } else{ get_control_ret := ccode | 0x0100; goto st1; finish; } } state st10 if(^make_ptd.do){ generate send_control.do(); goto st11; } state st11 if(^send_control.do){ if(send_control_ret==0){ get_control_ret := 0xF100; goto st1; finish; } else{ if(rbuf[0x0]<15:12>==0){ ccode := 0x0000; goto st12; } else{ get_control_ret := 0x010 || rbuf[0x0]<15:12>; goto st1; finish; } } } // Stage 2 (ccode==0) state st12 par{ // make_ptd(cbuf,SETUP,0,8,0,addr,port); generate make_ptd.do(TOKEN_SETUP, 0, 8, 0, 2, 2); goto st13; } state st13 if(^make_ptd.do){ any{ control_type=='D' : generate array_app_dev.do(); // array_app(cbuf+4,dev_req,4); control_type=='H' : generate array_app_hid.do(0x2200); // array_app(cbuf+4,hid_req,4); } goto st14; } state st14 if(^(array_app_dev.do | array_app_hid.do)){ cbuf[0b111] := 0x00 || DesSize; generate send_control.do(); goto st15; } state st15 if(^send_control.do){ if(send_control_ret==0) ccode := 0xF000; // new_make_ptd(cbuf,IN,0,MaxSize,1,addr,port,DesSize); generate new_make_ptd.do(TOKEN_IN, 0, MaxSize, 1, 2, 2, DesSize); goto st16; } state st16 if(^new_make_ptd.do){ generate send_control.do(); goto st17; } state st17 if(^send_control.do){ if(send_control_ret==0) ccode := 0xF00 || rbuf[0x0]<15:12>; else ccode := ccode | (0x000||rbuf[0x0]<15:12>); goto st18; } state st18 par{ if(ccode==0) goto st19; else{ get_control_ret := ccode | 0x0200; goto st1; finish; } } state st19 par{ mbuf_1 := rbuf[0x5]; goto st20; } // Stage3 (ccode==0) state st20 par{ // make_ptd(cbuf,OUT,0,0,toggle_cnt%2,addr,port); generate make_ptd.do(TOKEN_OUT, 0, 0, toggle_cnt, 2, 2); goto st21; } state st21 if(^make_ptd.do){ generate send_control.do(); goto st22; } state st22 if(^send_control.do){ get_control_ret := 0x030 || rbuf[0x0]<15:12>; goto st1; finish; } } // array_app(cbuf+4,dev_req,4); stage array_app_dev { state_name st1,st2,st3,st4; first_state st1; state st1 par{ cbuf[0b100] := 0x0680; goto st2; } state st2 par{ cbuf[0b101] := 0x0100; goto st3; } state st3 par{ cbuf[0b110] := 0x0000; goto st4; } state st4 par{ cbuf[0b111] := 8; goto st1; finish; } } // array_app(cbuf+4,hid_req,4); stage array_app_hid { state_name st1,st2,st3,st4; first_state st1; state st1 par{ cbuf[0b100] := 0x0681; goto st2; } state st2 par{ cbuf[0b101] := hid_req; goto st3; } state st3 par{ cbuf[0b110] := 0x0000; goto st4; } state st4 par{ cbuf[0b111] := 8; goto st1; finish; } } // new_make_ptd(cbuf,IN,0,MaxSize,1,addr,port,DesSize); // generate new_make_ptd.do(IN, 0, MaxSize, 1, 2, 2, DesSize); //void new_make_ptd(unsigned int *rptr,char token,char ep,int max,char tog,char addr,char port, unsigned int total) stage new_make_ptd { state_name st1,st2,st3,st4; first_state st1; state st1 par{ cbuf[0b000] := 0b0000 || 0b1 || tog || 0b0000000000; goto st2; } state st2 par{ // epは0 // max_size<8> cbuf[0b001] := 0b0000 || 0b0 || port2speed || 0b00 || max; goto st3; } state st3 par{ cbuf[0b010] := 0b0000 || token || 0b00 || total; goto st4; } state st4 par{ // addr<8> cbuf[0b011] := 0x00 || addr; goto st1; finish; } } // set_config(2,1); // set_config(int addr, int config) stage set_config { reg_wr mycode<16>; state_name st1,st2,st3,st4,st5,st6,st7,st7w,st8,st9,st10,st11,st12,st13; first_state st1; state st1 par{ generate w16.do(HcUpInt, 0x0100); goto st2; } state st2 if(^w16.do){ generate r32.do(HcATLDone); goto st3; } state st3 if(^r32.do){ generate r32.do(HcATLDone); goto st4; } state st4 if(^r32.do){ // make_ptd(cbuf,SETUP,0,8,0,addr,addr); generate make_ptd.do(TOKEN_SETUP, 0, 8, 0, 2, 2); goto st5; } state st5 if(^make_ptd.do){ generate array_app_uni.do(0x0900, 1); goto st6; } state st6 if(^array_app_uni.do){ generate send_control.do(); goto st7; } state st7 if(^send_control.do){ if(send_control_ret==0) mycode := 0xF00 || rbuf[0x0]<15:12>; else mycode := 0x000 || rbuf[0x0]<15:12>; goto st7w; } state st7w par{ if(mycode==0) goto st8; else goto st11; } state st8 par{ // mycode==0 // make_ptd(cbuf,IN,0,0,1,addr,addr); generate make_ptd.do(TOKEN_IN, 0, 0, 1, 2, 2); goto st9; } state st9 if(^make_ptd.do){ generate send_control.do(); goto st10; } state st10 if(^send_control.do){ if(send_control_ret==0) mycode := 0xF00 || rbuf[0x0]<15:12>; else mycode := 0x000 || rbuf[0x0]<15:12>; goto st11; } state st11 par{ generate r32.do(HcATLDone); goto st12; } state st12 if(^r32.do){ generate r32.do(HcATLDone); goto st13; } state st13 if(^r32.do){ set_config_ret := mycode; goto st1; finish; } } stage play_hid { reg_wr toggle; state_name st1,st2,st3,st4,st5,st5s,st6,st7,st8,st9,st10; first_state st1; state st1 par{ toggle := 0b0; generate erase_all.do(); goto st2; } state st2 if(^erase_all.do){ generate w16.do(HcBufStatus, 0x0000); goto st3; } state st3 if(^w16.do){ generate w32.do(HcIntSkip, 0xFFFFFFFE); goto st4; } state st4 if(^w32.do){ generate w32.do(HcIntLast, 0x00000001); goto st5; } state st5 if(^w32.do){ generate w16.do(HcIntBlkSize, 64); goto st5s; } state st5s if(^w16.do){ // generate array_app_hid.do(0x2200); // 0x2200? goto st6; } // do while state st6 if(^array_app_hid.do){ // make_int_ptd(cbuf,IN,1,8,tog%2,addr,addr,freq); generate make_int_ptd.do(TOKEN_IN, 1, 8, toggle, 2, 2, 0x00); goto st7; } state st7 if(^make_int_ptd.do){ generate send_int.do(); goto st8; } state st8 if(^send_int.do){ if(send_int_ret!=0){ breg_4 := rbuf[0x4]; breg_5 := rbuf[0x5]; breg_6 := rbuf[0x6]; toggle := ^toggle; } else{ breg_4 := 0x0000; breg_5 := 0x0000; breg_6 := 0x0000; } goto st9; } state st9 par{ generate r16.do(HcRhP2); goto st10; } state st10 if(^r16.do){ if(r16_ret<0>==0b1) goto st6; else{ breg_4 := 0x0000; breg_5 := 0x0000; breg_6 := 0x0000; goto st1; finish; } } } // make_int_ptd(char token, char ep, int max, char tog, char addr, char port, int freq) // make_int_ptd(cbuf,IN,1,8,tog%2,addr,addr,freq); stage make_int_ptd { state_name st1,st2,st3,st4; first_state st1; state st1 par{ cbuf[0b000] := 0b0000 || 0b1 || tog || 0b0000000000; goto st2; } state st2 par{ cbuf[0b001] := 0b000 || ep || 0b0 || port2speed || 0b00 || max; goto st3; } state st3 par{ cbuf[0b010] := 0b0000 || token || 0b00 || max; goto st4; } state st4 par{ cbuf[0b011] := freq || addr; goto st1; finish; } } stage send_int { reg_wr int_cnt<16>, wi_count<5>; state_name st1,st2,st3,st4,st5,st6,st7,st8,st9; first_state st1; state st1 par{ int_cnt := 50000; generate write_int.do(); goto st2; } state st2 if(^write_int.do){ generate w16.do(HcUpInt, 0x0080); goto st3; } state st3 if(^w16.do){ generate w16.do(HcBufStatus, 0x0004); goto st4; } state st4 if(^w16.do){ generate r32.do(HcIntDone); goto st5; } state st5 if(^r32.do){ generate r16.do(HcUpInt); wi_count := 0; int_cnt--; goto st6; } state st6 if(^r16.do){ wi_count++; if(/&wi_count){ // poll if((int_cnt!=0) & (r16_ret<7>==0b0)){ // active_bit=1 goto st5; } else goto st7; } } state st7 par{ generate w16.do(HcBufStatus, 0x0000); goto st8; } state st8 if(^w16.do){ // read_int(r_ptr, 72); generate read_int.do(); goto st9; } state st9 if(^read_int.do){ send_int_ret := int_cnt; goto st1; finish; } } stage write_int { reg_wr wi_cnt<3>; state_name st1,st2,st2w,st3,st4; first_state st1; state st1 par{ generate w16.do(HcTransferCnt, 16); goto st2; } state st2 if(^w16.do){ generate USB_HC_CMD_WRITE.do(0x00||(HcInt_Port|0x80)); wi_cnt := 0; goto st2w; } state st2w if(^USB_HC_CMD_WRITE.do){ // 必要のようだ rw_wait++; if(/&rw_wait) goto st3; } state st3 par{ generate USB_HC_DATA_WRITE.do(cbuf[wi_cnt]); goto st4; } state st4 if(^USB_HC_DATA_WRITE.do){ wi_cnt++; if(wi_cnt==7){ goto st1; finish; } else goto st3; } } stage read_int { reg_wr ri_cnt<4>; state_name st1,st2,st2w,st3,st4; first_state st1; state st1 par{ generate w16.do(HcTransferCnt, 32); goto st2; } state st2 if(^w16.do){ generate USB_HC_CMD_WRITE.do(0x00||HcInt_Port); ri_cnt := 0; goto st2w; } state st2w if(^USB_HC_CMD_WRITE.do){ // 必要のようだ rw_wait++; if(/&rw_wait) goto st3; } state st3 par{ generate USB_HC_DATA_READ.do(); goto st4; } state st4 if(^USB_HC_DATA_READ.do){ rbuf[ri_cnt] := Din_reg; ri_cnt++; if(ri_cnt==(16-1)){ goto st1; finish; } else goto st3; } } }