fl { MAX3241E driver PropForth 5.2 06/11/2012 19:30:18 MAX3241E Propeller SS ----- P16 MOSI ----- P17 RES ----- P18 GPX ----- P19 CLK ----- P20 MISO ----- P22 } hex \ ( n1 n2 n3 n4 -- ) n1:sending data(8bit) n2:_mosi n3:_miso n4:_clk lockdict create a_send_command forthentry $C_a_lxasm w, h126 h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z2WyPb1 l, zfiPeB l, z1SyLI[ l, z2WyPj1 l, zfiPmB l, z1SyLI[ l, z2WyPr1 l, zfiPuB l, z1SyLI[ l, zfyPOO l, z2WyQ88 l, zgyPO1 l, z1bfxZF l, z1[ZxZF l, z1bixZD l, z1[ixZD l, z3[yQCU l, z1SyLI[ l, z1SV01X l, freedict \ ( n1 n2 n3 n4 -- n5 ) n1:sending data(8bit) n2:_mosi n3:_miso n4:_CLK n5:receive data lockdict create a_byte_read forthentry $C_a_lxasm w, h126 h113 1- tuck - h9 lshift or here W@ alignl h10 lshift or l, z2WyPb1 l, zfiPeB l, z1SyLI[ l, z2WyPj1 l, zfiPmB l, z1SyLI[ l, z2WyPr1 l, zfiPuB l, z2WyQ88 l, z1bixZD l, zfy[b1 l, z2WiQ3E l, z1YiQ7l l, z20o[b1 l, z1[ixZD l, z3[yQCS l, z2WiPS\ l, z1SV01X l, 0 l, freedict 10 wconstant _ss 11 wconstant _mosi 12 wconstant _res 13 wconstant _gpx 14 wconstant _clk 15 wconstant _3421_clk 16 wconstant _miso wvariable Set_Address_to_7 -2 allot 00 c, 05 c, 07 c, 00 c, 00 c, 00 c, 00 c, 00 c, wvariable Get_Descriptor_Device -2 allot 80 c, 06 c, 00 c, 01 c, 00 c, 00 c, 00 c, 00 c, wvariable Get_Descriptor_Config -2 allot 80 c, 06 c, 00 c, 02 c, 00 c, 00 c, 00 c, 00 c, wvariable str -2 allot 80 c, 06 c, 00 c, 03 c, 00 c, 00 c, 00 c, 00 c, wvariable Set_Config -2 allot 00 c, 09 c, 01 c, 00 c, 00 c, 00 c, 00 c, 00 c, wvariable Get_Descriptor -2 allot 81 c, 06 c, 00 c, 22 c, 00 c, 00 c, 00 c, 00 c, wvariable class -2 allot 21 c, 0A c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, wvariable Set_Config_KB -2 allot 00 c, 09 c, 02 c, 00 c, 00 c, 00 c, 00 c, 00 c, : _ss_out_l _ss pinlo ; : _ss_out_h _ss pinhi ; : _clk_out_l _clk pinlo ; : _clk_out_h _clk pinhi ; : _mosi_out_l _mosi pinlo ; : _mosi_out_h _mosi pinhi ; : _res_out_l _res pinlo ; : _res_out_h _res pinhi ; : _gpx_out_l _gpx pinlo ; : _gpx_out_h _gpx pinhi ; _miso >m constant _misom wvariable maxPacketSize wvariable status wvariable nak_count wvariable nak_limit wvariable retry_count wvariable IN_nak_count wvariable xfrsize wvariable xfrlen wvariable last_transfer_size wvariable VID wvariable PID wvariable iMFG wvariable iPROD wvariable iSERIAL wvariable numConf wvariable iCONFIG wvariable Attr wvariable Power wvariable iINTERFACE wvariable wDESCLENGTH wvariable XfrData 100 allot \ data array \ Registers of MAX3421E d01 wconstant RCVFIFO d02 wconstant SNDFIFO d04 wconstant SUDFIFO d06 wconstant RCVBC d07 wconstant SNDBC 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 \ Constant h01 wconstant OSCOKIRQ \ USBIRQ h10 wconstant FDUPSPI \ PINCTL h01 wconstant HOST \ MODE h80 wconstant HXFRDNIRQ \ HIRQ h40 wconstant FRAMEIRQ \ HIRQ h20 wconstant CONDETIRQ \ HIRQ h04 wconstant RCVDAVIRQ \ HIRQ h20 wconstant RCVTOG1 \ HCTL h01 wconstant BUSRST \ HCTL h04 wconstant SAMPLEBUS \ HCTL \ Send 1 byte to MAX3421E \ (n1 -- ) n1:send data : a_byte_write _mosi _miso _clk a_send_command ; \ Send command-byte to register \ ( n1 n2 -- ) n1:register-data n2:register number : write_reg 3 lshift 2+ a_byte_write a_byte_write ; \ Read data from MAX3421E-register \ ( n1 -- n2 ) n1:register number n2:status : read_reg 3 lshift a_byte_write _mosi _miso _clk a_byte_read ; \ Write data to MAX3421E-register \ ( n1 n2 -- ) n1:register-data n2:register-number : Hwreg _ss_out_l write_reg _ss_out_h ; \ Write datas to FIFO \ (n1 n2 n3 -- ) n1:start-address for datas n2:numbers for write-byte n3:register-number : Hwritebytes _ss_out_l 3 lshift 2+ \ shift n3 to left 3bit and plus write-bit(0x2) \ send_command a_byte_write 0 do C@++ a_byte_write loop drop _ss_out_h ; \ Read data from MAX3421E-register \ ( n1 -- n2 ) n1:register-number n2:read-data : Hrreg _ss_out_l read_reg _ss_out_h ; \ Initialize MAX3421E \ ( -- ) : init_host \ Set output-register to 1 (_ss _mosi _res _gpx _clk _3421_clk) hF _ss lshift outa COG@ or outa COG! _ss 6 0 do dup pinout 1+ loop drop _clk_out_l \ Set _miso to input _miso pinin \ reset max3421e _res_out_l _res_out_h begin USBIRQ Hrreg OSCOKIRQ and 0= until OSCOKIRQ USBIRQ Hwreg \ ." init1 " HIRQ Hrreg . \ Set SPI to FullDuplex FDUPSPI PINCTL Hwreg \ ." init2 " HIRQ Hrreg . \ Set MODE to HOST HOST MODE Hwreg \ ." init3 " HIRQ Hrreg . cr d10 delms \ Delay when using SPI-assembler-word ; \ Check chip-revision : revision REVISION Hrreg ." Chip Revision:$" hex . decimal cr ; \ Set USB-device under removable : wait_disconnect ." Waiting for device disconnect" cr \ Clear IRQ CONDETIRQ HIRQ Hwreg \ Wait until CONDETIRQ is "0" begin HIRQ Hrreg CONDETIRQ and 0= until \ Turn off frame marker HOST MODE Hwreg ." Device disconnected" cr ; \ Detect FS or LS : detect_device ." Waiting for device connect" cr \ Set Host-mode and turn on 15k pulldown-R on D+ andD- HOST MODE Hwreg \ ." detect_device1 " HIRQ Hrreg . \ Clear CONDETIRQ-bit CONDETIRQ HIRQ Hwreg \ ." detect_device2 " HIRQ Hrreg . begin \ Sampling USB-Bus SAMPLEBUS HCTL Hwreg \ ." detect_device3 " HIRQ Hrreg . \ Check JSTATUS and KSTATUS HRSL Hrreg hC0 and dup if 1 else drop 0 then \ ." detect_device4 " HIRQ Hrreg . cr st? until 80 = if \ JSTATUS=1 \ Set Full-Speed-Mode hC9 MODE Hwreg \ ." Full " status W@ . ." Full-Speed Device Detected" else \ KSTATUS=1 \ Set Low-Speed-Mode hCB MODE Hwreg \ ." Low " status W@ . ." Low-Speed Device Detected" then cr ; \ ( n1 -- ) n1:loop counter : waitframe \ Clear FRAMEIRQ-bit FRAMEIRQ HIRQ Hwreg \ ." waitframe1 " HIRQ Hrreg . 0 do \ wait until FRAMEIRQ is set begin HIRQ Hrreg FRAMEIRQ and if 1 else 0 then until \ Clear FRAMEIRQ-bit FRAMEIRQ HIRQ Hwreg \ ." waitframe2 " HIRQ Hrreg . cr loop ; \ 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 \ Launch the transfer or HXFR Hwreg \ ." Send_Packet1 " HIRQ Hrreg . st? \ Wait for completion IRQ begin HIRQ Hrreg HXFRDNIRQ and if 1 else 0 then until \ wait until HXFRDNIRQ is set \ clear HXFRDNIRQ-bit HXFRDNIRQ HIRQ Hwreg \ ." Send_Packet_1 " HIRQ Hrreg . st? \ Get transfer-result HRSL Hrreg h0F and dup \ ." Send_Packet2 " HIRQ Hrreg . st? \ Check if peripheral reply hrNAK(0x04) 4 = if \ check if nak_count reach 200 1 nak_count W+! nak_count W@ d200 = \ ." nak_count" nak_count W@ . if 1 else drop 0 then else \ ." Send_Packet3" st? \ check if peripheral return hrTIMEOUT(0x0E) dup h0E = if \ check if retry_count reach 3 1 retry_count W+! retry_count W@ 3 = if 1 else drop 0 then \ ." retry_count" retry_count W@ . else 1 then then until \ ." Send_Packet4" st? ; \ 'IN_Transfer' to arbitray endpoint. \ ( n1 n2 -- n3) n1:endpoint n2:inbytes n3:resultcode HRSL(R31) : IN_Transfer \ ." IN_transfer0" st? xfrsize W! 0 xfrlen W! \ ." IN_transfer1" st? begin \ BULK-IN packet to EP* register HXFR dup 0 swap Send_Packet dup 0= \ ." IN_transfer2" st? \ it shoud be 0 when success(hrSUCCESS) if drop \ Get number of receives bytes RCVBC Hrreg dup \ ." IN_transfer3" st? \ get packet size \ Add packet's data to XfrData array 0 do RCVFIFO Hrreg \ dup . XfrData i + xfrlen W@ + C! loop \ Clear RCVDAVIRQ-bit RCVDAVIRQ HIRQ Hwreg \ st? \ ." IN_transfer4" st? \ 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 \ ." IN_transfer5" st? 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 \ ." IN_transfer6" st? ; \ 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 Hwritebytes \ ." CTL_Read0" st? \ Issue setup-packet to EP0 h10 0 Send_Packet dup 0= \ ." CTL_Read1 " HIRQ Hrreg . st? \ it shoud be 0 if success if \ st? drop \ Clear data toggle RCVTOG1 HCTL Hwreg \ ." CTL_Read2 " HIRQ Hrreg . \ byte-length for data stage 0 r> dup 6 + C@ swap 7 + C@ hFF u* + \ st? \ Get receive-data to XfrData array IN_Transfer dup 0= \ ." CTL_Read3 " HIRQ Hrreg . \ it shoud be 0 when success if drop nak_count W@ IN_nak_count W! \ Issue OUT-packet to EP0 A0 0 Send_Packet \ ." CTL_Read4 " HIRQ Hrreg . then else r> drop then \ ." CTL_Read4" st? ; \ 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 Hwritebytes h10 0 Send_Packet dup 0= \ ." A" st? if drop \ Issue IN-packet to EP0 h80 0 Send_Packet then \ ." B" st? ; \ 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 ." Exceeded NAK limit" else C over = if ." LS Timeout" else D over = if ." FS Timeout" else E over = if ." Device did not respond in time" else F over = if ." Device babbled (sent too long)" else ." Programing error " thens drop cr ; : test init_host detect_device ; decimal