fl hex : enumerate_device ." Issuing USB bus reset" cr \ register HCTL(R29) BUSRST 1 1d Hwreg \ wait until BUSRST is cleared begin 1d Hrreg 1 and if 0 else 1 then until c8 waitframe 8 maxPacketSize W! \ register PERADDR(R28) address 0 0 1c Hwreg \ set wLength_Low:Get_Descriptor_Device[6]=8 wLength_High:Get_Descriptor_Device[7]=0 8 Get_Descriptor_Device 2+ 6 + C! 0 Get_Descriptor_Device 2+ 7 + C! \ st? ." First 8 bytes of Device Descriptor ( " Get_Descriptor_Device 2+ CTL_Read dup \ ." enumerate1" st? if print_error else drop IN_nak_count W@ . ." NAKS )" cr XfrData 7 + C@ maxPacketSize W! last_transfer_size W@ 0 do XfrData i + C@ . loop cr ." EP0 maxPacketSize is " maxPacketSize W@ . ." bytes" cr ." Issuing USB bus reset" cr \ register HCTL(R29) BUSRST 1 1d Hwreg c8 waitframe ." Setting address to 0x07" cr Set_Address_to_7 2+ CTL_Write_ND dup if print_error else drop 1e waitframe \ register PERADDR(R28) 7 1c Hwreg 12 Get_Descriptor_Device 2+ 6 + C! ." Device Descriptor ( " Get_Descriptor_Device 2+ CTL_Read dup if print_error else drop IN_nak_count W@ . ." NAKS )" cr ." -----------------" cr XfrData 8 + C@ XfrData 9 + C@ ff u* + VID W! XfrData a + C@ XfrData b + C@ ff u* + PID W! XfrData e + C@ iMFG W! XfrData f + C@ iPROD W! XfrData 10 + C@ iSERIAL W! last_transfer_size W@ 0 do XfrData i + C@ . loop cr ." USB " XfrData 3 + C@ 30 + emit 2e emit XfrData 2 + C@ . cr ." This device has " XfrData 11 + C@ . ." configuration" cr ." Vendor ID is 0x" VID W@ . cr ." Product ID is 0x" PID W@ . cr 0 str 2+ 2+ C! \ index 0 is language ID string 0 str 2+ 4 + C! \ lang ID is 0 0 str 2+ 5 + C! 4 str 2+ 6 + C! \ wLengthL 0 str 2+ 7 + C! \ wLengthH str 2+ CTL_Read 0= \ Get lang ID string if \ Check for ACK (could be a STALL if the device has no strings) ." Language ID String Descriptor is " last_transfer_size W@ 0 do XfrData i + C@ . loop cr XfrData 2+ C@ str 2+ 4 + C! \ LangID-L XfrData 3 + C@ str 2+ 5 + C! \ LangID-H ff str 2+ 6 + C! \ now request a really big string then iMFG W@ if iMFG W@ str 2+ 2+ C! str 2+ CTL_Read drop \ Get Manufacturer ID string ." Manuf. string is " last_transfer_size W@ 2 do XfrData i + C@ emit 2 +loop else ." There is no Manuf. string" then cr iPROD W@ if iPROD W@ str 2+ 2+ C! str 2+ CTL_Read drop \ Get Product ID string ." Product string is " last_transfer_size W@ 2 do XfrData i + C@ emit 2 +loop else ." There is no Product string" then cr iSERIAL W@ if iSERIAL W@ str 2+ 2+ C! str 2+ CTL_Read drop \ Get Serial Number ID string ." S/N string is " last_transfer_size W@ 2 do XfrData i + C@ . 2 +loop else ." There is no Serial Number" then cr \ Get the 9-byte configuration descriptor ." Configuration Descriptor ( " 9 Get_Descriptor_Config 2+ 6 + C! 0 Get_Descriptor_Config 2+ 7 + C! Get_Descriptor_Config 2+ CTL_Read dup 0= \ Get config descriptor into XfrData[] if drop IN_nak_count W@ . ." NAKS )" cr ." ------------------------" cr last_transfer_size W@ 0 do XfrData i + C@ . loop cr XfrData 2+ C@ Get_Descriptor_Config 2+ 6 + C! \ LengthL XfrData 3 + C@ Get_Descriptor_Config 2+ 7 + C! \ LengthH Get_Descriptor_Config 2+ CTL_Read drop \ Get config descriptor into XfrData[] ." Full Configuration Data" cr last_transfer_size W@ 0 do i f and 0= if cr then \ CR every 16 numbers XfrData i + C@ . loop cr XfrData 6 + C@ iCONFIG W! \ optional configuration string ." Configuration " XfrData 5 + C@ . ." has " XfrData 4 + C@ . ." interface" XfrData 4 + C@ 1 > if ." s" then cr ." This device is " XfrData 7 + C@ 40 = if ." self-powered" else ." bus powered and uses " XfrData 8 + C@ 2 u* . ." milliamps" then cr XfrData 11 + C@ str 2+ 2+ C! str 2+ CTL_Read drop last_transfer_size W@ 0 do XfrData i + C@ emit loop cr \ Parse the config+ data for interfaces and endpoints. Skip over everything but \ interface and endpoint descriptors. EP0 EP1 ..... EPn 0 \ counter begin dup XfrData 1+ + C@ dup >r 4 = if ." Interface " dup XfrData 2+ + C@ . ." Alternate Setting " dup XfrData 3 + + C@ . ." has:" r> drop else r> 5 = if ." --Endpoint " dup XfrData 2+ + C@ f and . dup XfrData 2+ + C@ 80 and if ." -IN" else ." -OUT" then dup XfrData 4 + + C@ . ." is type " dup XfrData 3 + + C@ 3 and 0 over = if ." CONTROL" else 1 over = if ." ISOCHRONOUS" else 2 over = if ." BULK" else 3 over = if ." INTERRUPT with a polling interval of " over XfrData 6 + + C@ . ." msec" then then then then drop cr then then last_transfer_size W@ + dup dup \ uodate counter XfrData + C@ < if 1 else 0 then until \ ." emu-end" st? drop iCONFIG W@ if iCONFIG W@ str 2+ 2+ C! str 2+ CTL_Read drop \ Get Config string ." Config string is " last_transfer_size W@ 2 do XfrData i + C@ emit \ . 2 +loop else ." There is no Config string" then cr then then then then ; : usb init_host detect_device c8 waitframe enumerate_device wait_disconnect ; decimal