fl fl { Display USB-descriptor by using MAX3241E PropForth 5.5 (Xtal on DemoBoard is 6MHz) 2015/01/10 23:19:55 DemoBoard MAX3241E Propeller RES ----- P0 SCK ----- P1 SS ----- P2 MOSI ----- P3 XI ----- P4(Clock for MAX3421E) MISO ----- P5 INT ----- P6(with pullup resister 10kohm) using MAX3421E Chip Revision is h13. } \ allocate string \ ( -- ) : s, parsenw dup C@ 1+ bounds dup rot2 do C@++ c, loop drop ; \ ------------------------------------------------------- \ Constants \ ------------------------------------------------------- h1F8 wconstant ctra h1FA wconstant frqa 0 wconstant _res 1 wconstant _sck 2 wconstant _ss 3 wconstant _mosi 4 wconstant _xi 5 wconstant _miso 6 wconstant _int wvariable Set_Address_to_7 -2 allot h00 c, h05 c, h07 c, h00 c, h00 c, h00 c, h00 c, h00 c, wvariable Get_Descriptor_Device -2 allot h80 c, h06 c, h00 c, h01 c, h00 c, h00 c, h00 c, h00 c, wvariable Get_Descriptor_Config -2 allot h80 c, h06 c, h00 c, h02 c, h00 c, h00 c, h00 c, h00 c, wvariable str -2 allot h80 c, h06 c, h00 c, h03 c, h00 c, h00 c, h00 c, h00 c, wvariable Set_Config -2 allot h00 c, h09 c, h01 c, h00 c, h00 c, h00 c, h00 c, h00 c, wvariable Get_Descriptor -2 allot h81 c, h06 c, h00 c, h22 c, h00 c, h00 c, h00 c, h00 c, wvariable class -2 allot h21 c, h0A c, h00 c, h00 c, h00 c, h00 c, h00 c, h00 c, : _res_out_l _res pinlo ; : _res_out_h _res pinhi ; : _sck_out_l _sck pinlo ; : _sck_out_h _sck pinhi ; : _ss_out_l _ss pinlo ; : _ss_out_h _ss pinhi ; : _mosi_out_l _mosi pinlo ; : _mosi_out_h _mosi pinhi ; _miso >m constant _misom _int >m constant _intm \ Register \ Registers of MAX3421E d01 wconstant RCVFIFO d02 wconstant SNDFIFO d04 wconstant SUDFIFO d06 wconstant RCVBC d07 wconstant SNDBC d12 wconstant EPIEN d13 wconstant USBIRQ d14 wconstant USBIEN d15 wconstant USBCTL d16 wconstant CPUCTL d17 wconstant PINCTL d18 wconstant REVISION d20 wconstant IOPIN1 d21 wconstant IOPIN2 d22 wconstant GPINIRQ d23 wconstant GPINIEN d24 wconstant GPINPOL d25 wconstant HIRQ d26 wconstant HIEN d27 wconstant MODE d28 wconstant PERADDR d29 wconstant HCTL d30 wconstant HXFR d31 wconstant HRSL \ Register bit h01 wconstant OSCOKIRQ \ USBIRQ h20 wconstant CHIPRES \ USBCTL h01 wconstant IE \ CPUCTL h10 wconstant FDUPSPI \ PINCTL h08 wconstant INTLEVEL \ PINCTL h80 wconstant DPDN \ MODE h40 wconstant DMDN \ MODE h08 wconstant SOF \ MODE h01 wconstant HOST \ MODE h80 wconstant HXFRDNIRQ \ HIRQ h40 wconstant FRAMEIRQ \ HIRQ h20 wconstant CONDETIRQ \ HIRQ h10 wconstant SUSDNIRQ \ HIRQ h04 wconstant RCVDAVIRQ \ HIRQ h02 wconstant RWUIRQ \ HIRQ h01 wconstant BUSEVENTIRQ \ HIRQ h40 wconstant FRAMEIE \ HIEN h20 wconstant CONDETIE \ HIEN h10 wconstant SUSDNIE \ HIEN h02 wconstant RWUIE \ HIEN h01 wconstant BUSEVENTIE \ HIEN h20 wconstant RCVTOG1 \ HCTL h01 wconstant BUSRST \ HCTL h04 wconstant SAMPLEBUS \ HCTL \ Strings wvariable main -2 allot s, Input s, Output s, Collection s, Feature s, EndCollection wvariable global -2 allot s, UsagePage s, LogicalMinimum s, LogicalMaximum s, PhysicalMinimum s, PhysicalMaximum s, UnutExponent s, Unit s, ReportSize s, ReportID s, ReportCount s, Push s, Pop wvariable local -2 allot s, Usage s, UsageMinimum s, UsageMaximum s, DesignatorIndex s, DesignatorMinimum s, StringIndex s, StringMinimum s, StringMaximum s, Delimiter wvariable Attribute -2 allot s, Data s, Constant s, Array s, Variable s, Absolute s, Relative wvariable Collection -2 allot s, Physical s, Application s, Logical s, Report s, NamedArray s, UsageSwitch s, UsageModifier wvariable UsagePage -2 allot s, Undefined s, Generic_Desktop_Controls s, Simulation_Controls s, VR_Controls s, Sport_Controls s, Game_Controls s, Generic_Device_Controls s, Keyboard/Keypad s, LEDs s, Button s, Ordinal s, Telephony s, Consumer wvariable Generic_Desktop_Page -2 allot s, Undefined s, Pointer s, Mouse s, Reserved s, Joystick s, Game_Pad s, Keyboard s, Keypad s, Multi-axis_Controller s, X s, Y s, Z s, Rx s, Ry s, Rz s, Slider s, Dial s, Wheel \ ------------------------------------------------------- \ Variables \ ------------------------------------------------------- wvariable status wvariable nak_count wvariable nak_limit wvariable retry_count wvariable xfrsize wvariable xfrlen wvariable VID wvariable PID wvariable iMFG wvariable iPROD wvariable iSERIAL wvariable numConf wvariable iCONFIG wvariable Attr wvariable Power wvariable iINTERFACE wvariable wDESCLENGTH \ size of report descriptor wvariable Size \ data packet size wvariable tmp wvariable report_array 3 allot wvariable count \ This variables also are used in assembler-word'CTL_Read' wvariable maxPacketSize wvariable last_transfer_size wvariable IN_nak_count wvariable XfrData 100 allot \ data array \ ------------------------------------------------------- \ Main \ ------------------------------------------------------- \ ------------- Basic command for MAX3421E ------------------- \ Lock accessing to MAX3421E \ ( -- ) : MAX_lock begin 6 _lockarray + C@ h0F = if 6 lock 1 else 0 then until _sck pinout _ss pinout _mosi pinout _ss_out_l ; \ Unlock accessing to MAX3421E \ ( -- ) : MAX_unlock _ss_out_h _sck pinin _ss pinin _mosi pinin 6 unlock ; \ Send 1 byte to MAX3421E \ (n1 -- ) n1:send data(1byte) : byte_wr h80 8 0 do 2dup and if _mosi_out_h \ ." 1" else _mosi_out_l \ ." 0" then _sck_out_h 1 rshift _sck_out_l loop 2drop ; \ Read data from register \ ( -- n1) n1:response : byte_rd 0 8 0 do 1 lshift _sck_out_h _misom _maskin if 1 or then _sck_out_l loop ; \ Write multiple-bytes to FIFO \ (n1 n2 n3 -- ) n1:start-address for datas n2:numbers for write-byte n3:register-number : MAXbytes_wr MAX_lock 3 lshift 2+ \ Shift register number and add 2(wr-bit) byte_wr \ Send command \ ( n1 n2 ) 0 do C@++ byte_wr loop drop MAX_unlock ; \ Write data(1byte) to MAX3421E-register \ ( n1 n2 -- ) n1:register-data n2:register-number : MAXreg_wr MAX_lock 3 lshift 2+ \ Shift register number and add 2(wr-bit) byte_wr \ Send command byte_wr \ Send dta(1byte) \ 1 delms MAX_unlock ; \ Read data(1byte) from MAX3421E-register \ ( n1 -- n2 ) n1:register-number n2:read-data : MAXreg_rd MAX_lock 3 lshift \ Shift register number byte_wr \ Send command byte_rd \ Receive data(1byte) MAX_unlock ; \ Check chip-revision \ ( -- ) : Rev. REVISION MAXreg_rd ." Chip Revision:h" . cr ; \ Reset MAX3241E : res_chip CHIPRES USBCTL MAXreg_wr \ chip reset 0 USBCTL MAXreg_wr \ remove reset \ bmFDUPSPI bmINTLEVEL FDUPSPI INTLEVEL or PINCTL MAXreg_wr \ Wait until oscillator is stable begin USBIRQ MAXreg_rd OSCOKIRQ and st? 0<> until ; \ Detect FS or LS \ ( -- ) : detect_device HIRQ MAXreg_rd . ." Waiting for device connect" cr begin \ Check JSTATUS and KSTATUS HRSL MAXreg_rd ." HRSL:" dup . hC0 and dup if 1 else drop 0 then until h80 = if \ JSTATUS=1(Under LOWSPEEDbit=0) \ Set Full-Speed-Mode hC9 MODE MAXreg_wr \ Full speed ." Full-Speed Device Detected" else \ KSTATUS=1(Under LOWSPEEDbit=0) \ Set Low-Speed-Mode hCB MODE MAXreg_wr \ Low speed ." Low-Speed Device Detected" then cr ." HIRQ " HIRQ MAXreg_rd . MODE MAXreg_rd . cr ; \ -------------------------------------------------------------------------------------------------- \ Procedure inside interupt \ -------------------------------------------------------------------------------------------------- \ Write data(1byte) to MAX3421E-register during interupt \ ( n1 n2 -- ) n1:register-data n2:register-number : MAXreg_wr_int 3 lshift 2+ \ Shift register number and add 2(wr-bit) byte_wr \ Send command byte_wr \ Send dta(1byte) ; \ Read data(1byte) from MAX3421E-register during interupt \ ( n1 -- n2 ) n1:register-number n2:read-data : MAXreg_rd_int 3 lshift \ Shift register number byte_wr \ Send command byte_rd \ Receive data(1byte) ; : detect_device_int begin \ Check JSTATUS and KSTATUS HRSL MAXreg_rd_int hC0 and dup if 1 else drop 0 then until h80 = if \ JSTATUS=1 \ Set Full-Speed-Mode hC9 MODE MAXreg_wr_int \ Full speed else \ KSTATUS=1 \ Set Low-Speed-Mode hCB MODE MAXreg_wr_int \ Low speed then ; variable flag \ service_irq \ ( -- ) : interupt 0 flag L! d16 pinout d17 pinout d18 pinout d19 pinout begin d16 pinhi d17 pinhi \ Wait during _int is Hi _intm _intm waitpeq \ Wait until _int goes to Lo _intm _intm waitpne d18 pinhi d19 pinhi MAX_lock begin \ detect_device_int \ CONDETIRQ HIRQ MAXreg_wr_int d16 pinlo \ flag C@ 1+ flag C! \ HIRQ MAXreg_rd_int CONDETIRQ over = HIRQ MAXreg_rd_int CONDETIRQ = if CONDETIRQ HIRQ MAXreg_wr_int d16 pinlo flag C@ 1+ flag C! else BUSRST HCTL MAXreg_wr_int begin HCTL MAXreg_rd_int BUSRST and if 0 else 1 then until SUSDNIRQ HIRQ MAXreg_wr_int d17 pinlo flag 1+ C@ 1+ flag 1+ C! then { else SUSDNIRQ over = if SUSDNIRQ HIRQ MAXreg_wr_int d17 pinlo flag 1+ C@ 1+ flag 1+ C! else RWUIRQ over = if RWUIRQ HIRQ MAXreg_wr_int d18 pinlo flag 2+ C@ 1+ flag 2+ C! else \ 8 HCTL a_Hwreg BUSEVENTIRQ HIRQ MAXreg_wr_int d19 pinlo flag 3 + C@ 1+ flag 3 + C! thens drop } \ Break loop if _int is Hi ina COG@ _intm and until MAX_unlock 0 until ; \ -------------------------------------------------------------------------------------------------- \ Initialize MAX3421E \ ( -- ) : init_MAX3421E hex \ ---- MAX3421E is peripheral mode. \ generate 12MHz with NCO mode (prop frequency:96MHz) h10000004 ctra COG! h20000000 frqa COG! _xi pinout \ H/W reset _res pinout _res_out_h _res_out_l _res_out_h \ Set output-register to 1 (_ss) 5 outa COG! \ Reset peripheral res_chip \ ---- Configure full-duplex, interrupt level \ ---- MAX3421E is host mode. \ Set Host-mode and turn on 15k pulldown-R on D+ andD- DPDN DMDN or HOST or MODE MAXreg_wr CONDETIE HIEN MAXreg_wr SAMPLEBUS HCTL MAXreg_wr \ Check if anything is connected detect_device \ Enable interrupt pin \ CONDETIE SUSDNIE or RWUIE or BUSEVENTIE or HIEN a_Hwreg CONDETIE SUSDNIE or HIEN MAXreg_wr ." HIEN:" HIEN MAXreg_rd . \ Clear CONDETIRQ HIRQ MAXreg_wr SUSDNIRQ HIRQ MAXreg_wr RWUIRQ HIRQ MAXreg_wr BUSEVENTIRQ HIRQ MAXreg_wr \ c" interupt" 0 cogx ." HIRQ:" HIRQ MAXreg_rd . \ Enable interrupt pin IE CPUCTL MAXreg_wr ; \ Set USB-device under removable : wait_disconnect ." Waiting for device disconnect" cr \ Clear IRQ CONDETIRQ HIRQ MAXreg_wr \ Wait until CONDETIRQ is "0" begin HIRQ MAXreg_rd CONDETIRQ and 0= until \ Turn off frame marker HOST MODE MAXreg_wr ." Device disconnected" cr ; \ \ ( n1 -- ) n1:loop counter : waitframe 0 do \ Clear FRAMEIRQ-bit FRAMEIRQ HIRQ MAXreg_wr ." a " \ wait until FRAMEIRQ is set begin HIRQ MAXreg_rd FRAMEIRQ and if 1 else 0 then until loop \ Clear FRAMEIRQ-bit FRAMEIRQ HIRQ MAXreg_wr ." waitframe1 " HIRQ MAXreg_rd . cr ; \ send USB_packet \ ( n1 n2 -- n3 ) n1:token n2:endpoint number n3:resultcode HRSL(R31) \ token SETUP :0x10 \ BULK-IN :0x00 + ep \ BULK-OUT:0x20 + ep \ HS-IN :0x80 + ep \ HS-OUT :0xA0 + ep \ ISO-IN :0x40 + ep \ ISO-OUT :0x60 + ep : Send_Packet 0 nak_count W! 0 retry_count W! begin 2dup \ Launch the transfer or HXFR MAXreg_wr \ Wait for completion IRQ begin HIRQ MAXreg_rd HXFRDNIRQ and if 1 else 0 then until \ clear HXFRDNIRQ-bit HXFRDNIRQ HIRQ MAXreg_wr \ Get transfer-result HRSL MAXreg_rd ." HRSL:" dup . h0F and dup \ Check if peripheral reply hrNAK(0x04) 4 = if \ check if nak_count reach 200 1 nak_count W+! nak_count W@ d200 = if rot2 2drop 1 else drop 0 then else \ check if peripheral return hrTIMEOUT(0x0E) dup h0E = if \ check if retry_count reach 3 1 retry_count W+! retry_count W@ 3 = if rot2 2drop 1 else drop 0 then else rot2 2drop 1 then then until ; \ 'IN_Transfer' to arbitray endpoint. \ ( n1 n2 -- n3) n1:endpoint n2:inbytes n3:resultcode HRSL(R31) : IN_Transfer xfrsize W! 0 xfrlen W! begin \ BULK-IN packet to EP* register HXFR dup 0 swap Send_Packet dup 0= \ it shoud be 0 when success(hrSUCCESS) if drop \ Get number of receives bytes RCVBC MAXreg_rd dup \ Add packet's data to XfrData array 0 do RCVFIFO MAXreg_rd XfrData i + xfrlen W@ + C! loop \ Clear RCVDAVIRQ-bit RCVDAVIRQ HIRQ MAXreg_wr \ Add packet's byte to total dup xfrlen W+! \ Conditions when transfer is complete \ 1.The device sent a short packet(less than maxPacketSize) \ 2.'INbytes' have been tranferred maxPacketSize W@ < xfrlen W@ xfrsize W@ >= or if xfrlen W@ last_transfer_size W! drop 0 1 \ return resultcode 0 else 0 then else nip 1 \ return resultcode is not 0 then until ; \ CONTROL-Read Transfer \ Send CONTROL \ (n1 -- n2 ) n1:Descriptor_Type's address n2:0(success) not zero(error code) : CTL_Read dup >r \ write Get_Descriptor_Device's datas to SUDFIFO(R4) 8 SUDFIFO MAXbytes_wr \ Issue setup-packet to EP0 h10 0 Send_Packet dup 0= \ it shoud be 0 if success if drop \ Clear data toggle RCVTOG1 HCTL MAXreg_wr \ byte-length for data stage 0 r> dup 6 + C@ swap 7 + C@ hFF u* + \ Get receive-data to XfrData array HCTL MAXreg_rd 8 or HCTL MAXreg_wr begin HCTL MAXreg_rd 8 and 0= until IN_Transfer dup 0= \ it shoud be 0 when success if drop nak_count W@ IN_nak_count W! HCTL MAXreg_rd 8 or HCTL MAXreg_wr begin HCTL MAXreg_rd 8 and 0= until \ Issue OUT-packet to EP0 hA0 0 Send_Packet then else r> drop then ; \ Execute CONTROL-write without data \ ( n1 -- n2 ) n1:data's address n2:resultcode HRSL(R31) : CTL_Write_ND \ Issue setup-packet to EP0 8 SUDFIFO MAXbytes_wr \ h10 0 a_Send_Packet dup 0= h10 0 Send_Packet dup 0= if drop \ Issue IN-packet to EP0 h80 0 Send_Packet then ; \ display error-message \ ( n1 -- ) ni:error code : print_error ." >>>>> Error >>>>>" cr 1 over = if ." MAX3421E SIE is busy" else 2 over = if ." Bad value in HXFR register" else 4 over = if ." NAK returned" else 5 over = if ." STALL returned" else 6 over = if ." Toggle error" else 7 over = if ." incorrect PID" else 8 over = if ." Illegal bytecount" else 9 over = if ." PID corrision" else hA over = if ." Packey error" else hB over = if ." CRC error" else hC over = if ." No response K-status" else hD over = if ." No response J-status" else hE over = if ." Device did not respond in time" else hF over = if ." Device babbled (sent too long)" else ." Programing error " thens drop cr ; \ Print datas inside XfrData array \ ( -- ) : Print_data last_transfer_size W@ 0 do XfrData i + C@ . loop ; \ Print datas inside XfrData array as character \ ( -- ) : print_char last_transfer_size W@ 2 do XfrData i + C@ emit 2 +loop ; : tab 9 emit ; : 2tab tab tab ; : 3tab tab tab tab ; \ Display string \ ( n1 n2 -- ) n1:string index n2:string's top address : dispStr swap dup 0 <> if 0 do dup C@ + 1+ loop else drop then .cstr ; \ Print ( and ) \ ( -- ) : ( bl emit h28 emit ; : ) h29 emit ; \ Display attribute \ ( n -- ) n:attribute data : dispAttribute 1 3 0 do 2dup and if 1 else 0 then i 2 u* + Attribute dispStr i 2 < if ." ," then 1 lshift loop 2drop ;