fl { MAX3241E driver PropForth 5.2 29/10/2012 14:29:43 MAX3241E Propeller SS ----- P16 MOSI ----- P17 RES ----- P18 GPX ----- P19 CLK ----- P20 MAX3421E_clk --- P21 MISO ----- P22 This code occupy 5560bytes in memory. } 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:_mosi n2:_miso n3:_clkn5: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 1F8 wconstant ctra 1FA wconstant frqa 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 iCONFIG wvariable iINTERFACE wvariable wDESCLENGTH wvariable XfrData 100 allot \ data array \ wvariable status \ 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 hC1 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 { \ Read data from register \ ( -- n1) n1:response : byte_read 0 8 0 do 1 lshift _clk_out_h _misom _maskin if 1 or then _clk_out_l loop ; } \ 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 \ generate 12MHz with NCO mode \ h10000015 ctra COG! h26666666 frqa COG! \ reset max3421e _res_out_l _res_out_h begin USBIRQ Hrreg OSCOKIRQ and 0= until OSCOKIRQ USBIRQ Hwreg \ ." init1 " status W@ . \ Set SPI to FullDuplex FDUPSPI PINCTL Hwreg \ ." init2 " status W@ . \ Set MODE to HOST HOST MODE Hwreg \ ." init3 " status W@ . 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 hC1 MODE Hwreg ." Device disconnected" cr ; \ Detect FS or LS : detect_device \ Set Host-mode and turn on 15k pulldown-R on D+ andD- hC1 MODE Hwreg \ ." detect_device1 " status W@ . \ Clear CONDETIRQ-bit CONDETIRQ HIRQ Hwreg \ HIRQ Hrreg ." HIRQ:" . ." detect_device2 " status W@ . ." Waiting for device connect" cr begin \ Sampling USB-Bus SAMPLEBUS HCTL Hwreg \ ." detect_device3 " status W@ . st? 1 delms \ Check JSTATUS and KSTATUS HRSL Hrreg hC0 and dup \ ." detect_device4 " status W@ . cr st? if 1 else drop 0 then 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 " status W@ . 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 " status W@ . 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" 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" st? \ Get transfer-result HRSL Hrreg h0F and dup \ ." Send_Packet2" 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" st? \ it shoud be 0 if success if \ st? drop \ Clear data toggle RCVTOG1 HCTL Hwreg \ ." CTL_Read2" st? \ 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" st? \ it shoud be 0 when success if drop nak_count W@ IN_nak_count W! \ Issue OUT-packet to EP0 A0 0 Send_Packet 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 ;