I'm trying to enable USB 2.0 Host on an AST2500 based board. I'm using the latest obmc-phosphor-image from GitHub which contains Linux 5.10.30. EHCI seems to start in QEMU but fails on real HW. I enabled ehci0 (or ehci1) in the device tree, added the necessary drivers to Linux and I get the following error message during boot-up:
ehci-platform 1e6a1000.usb: USB 2.0, controller refused to start: -110
I investigated EHCI registers a bit and found that when ehci_run() function in ehci-hcd.c would start EHCI (by setting CMD_RUN bit) it remains halted, HCHalted bit in USBSTS register remains 1.
I also saw that the frame index register starts to count when CMD_RUN is asserted. Clock and reset bits in SCU registers are set properly by pinctrl and clk drivers.
Contents of the periodic list buffer and the asynchronous QH buffer seem to be OK. But EHCI still doesn't start.
Strangely UHCI (USB 1.1 host) seems to work properly.
Did maybe somebody manage to get EHCI working on real AST2500 or similar hardware?
Thanks for any advice.
Related
I am using a Zebra DS457 Scanner to read bar and qr codes via COM-Port (RS232). In my test evironment I used a MSI terminal with Win10 and it worked on the real COM-Port without any problems. But on other devices (Win10 and Win7) there are some issues that the software trigger does not come through and the read information do not get sent back to the computer. When I am using a USB to RS232 FTDI adapter I have no issues at all. But why? First I thought it is Win10 and the legacy support could be better, but the adapter is on all devices better and faster. How is this possible? Maybe a driver specific thing? I am using this adapter link to conrad.de.
An FTDI serial port will impose a minimum latency between the time a character arrives over the wire and when an application can see it, and between the time an application wants to send something and the time it goes over a wire. On older devices, these latencies were a minimum of 1ms each, but I think some newer high speed devices have reduced them to 125us. Further, data which arrives at just the wrong speed sometimes ends up with hundreds of milliseconds of additional latency, for reasons I don't quite understand.
On the other hand, an FTDI device can buffer 256 bytes of data from the wire, or 128 bytes of data from the USB port to be sent over the wire, and process RTS/CTS handshaking, without any software intervention--abilities which are lacking in the UART chips used by PC serial ports. If software gives 128 bytes to an FTDI device, it will start sending it until the remote device deasserts its handshake line, whereupon the FTDI device will stop sending as soon as the current byte is complete; it will then resume transmission as soon as the remote device reasserts handshake. If an FTDI device receives enough data over the wire that its UART would be in danger of overflowing, it will automatically deassert its handshake output without requiring any software intervention. The UART used in PC serial port, by contrast, requires a fast interrupt handler to control or respond to the handshake wires. If an interrupt handler maintains a 4096-byte buffer, it may deassert the handshake wire once that buffer is 75% full, but nothing would deassert the handshake wire if the buffer is less than 75% full and 17 bytes arrive over the wire in quick succession before the UART interrupt handler. Worse, if transmit buffering is enabled, and the PC has fed 16 bytes to the UART for transmission when the remote device deasserts its handshake line, those 16 bytes will be sent out whether or not the remote device is ready to receive them (and based upon the handshake wire, it very well might not be).
Thus, some applications can work much better with an FTDI UART, and some much better with an actual serial port.
I am looking into USB device driver code. looks like all it does is to fill a URB message then calls usb_submit_urb() to pass the message to USB core functions once probe() is called upon matching PCI vendor/product ID.
However I am not able to figure out how USB core relates the device driver to correct HCI driver (xHCI, eHCI etc.)... what I found is most of HCI drivers register themselves as a platform driver which has a unique name, is that the identifier for usb core to correlate the device driver and host driver?
When you have usb 3.0 - then kernel uses xhci driver and doesn't need uhci, ohci or ehci drivers. In such configuration you have got only one hci driver and one hci host. Earlier in the USB 2.0 era there were 2 possible configurations:
ehci with companion controller (ohci or uhci)
ehci with transaction translator (TT)
In the first situation you need to have both drivers installed - for example ehci and uhci. In the second one only dedicated ehci driver was needed.
So currently when you have only xhci - it registers itself as the only usb host driver in linux system. Second thing - it is host driver function to request anything from usb devices - so usb host generates any requests to devices and it is responsible for maintenance of the answers from device. The xhci host driver registers his interrupt and memory area for request maintenance.
I think you need to take a look at this problem from the host (xhci) point of view, not from device point of view, because the host is the master in usb communication and the host initiates any requests. Device is only answering those requests.
I have connected a PiCAN2 board with raspberry pi running latest Jessie. When I try to send some CAN messages to my PC ( PC is connected via a USB to DB9 CAN interface to the PiCAN2 board) through this PiCAN2 using the can-utils, it runs into ERROR-PASSIVE state as soon as I bring the CAN interface up. But, when I enable loopback mode, I am able to send messages and receive them using two different terminal window on the raspberry pi itself. I enabled loopback mode using
sudo /sbin/ip link set can0 type can bitrate 500000 loopback on.
Can some one tell me more about the loopback mode? I want to make sure that my hardware setup for PiCAN2 is correct. Is it possible to confirm that my CAN board is configured correctly because I can send/receive messages using loopback mode?Or this doesn't necessarily mean that it is correct?
I also want to know why I get the ERROR PASSIVE mode - does it indicate that the PiCAN2 is not configured correctly OR does it mean that my USB to DB9 CAN interface has some problem? I am new to this area and any help would be nice. Thank you.
I have a new Intel Edison connected to the Arduino breakout board and it is unable to boot. I have never seen it boot ever.
I have tried connecting it with different settings to discard a problem at cable level or power input.
The current setup is:
-Intel Edison mounted on Arduino breakout board.
-Power cable connected to Powered USB Hub or to wall adapter.
-Console cable connected directly to computer USB port.
When monitoring the boot process with a terminal app, the only output is:
PSH KERNEL VERSION: b0182727
..WR: 20104000
SCU IPC: 0x800000d0 0xfffce92c
PSH miaHOB version: TNG..B0..VVBD..0000000c
microkernel. built 23:15:13. Apr 24 2014.
******* PSH loader *******
PCM page cache size = 192 KB
Cache Constraint = 0 Pages
Arming IPC driver ..
Adding page store pool ..
PagestoreAddr(IMR Start Address) = 0x04899000
pageStoreSize(IMR Size) = 0x00080000
**** Ready to receive application ****
After this, the Edison loops every X amount of time. If I disconnect and reconnect power, the exact result is obtained.
I have also tried to boot from OsX / Debian / Linux with no results.
When running the flashall.sh scripts, the device is never found.
I have tried everything I have found online, and have run out of ideas...
I am now sure the Edison has a physical problem. I tried with a new one and was able to boot it up without any trouble. I already talked to the company I bought it from and they will be doing a refund.
I'd like to write a Ruby program for OSX that communicates via USB with my Arduino.
I am going to use the serialport gem for that purpose.
I found a sample code that says:
port_str = "/dev/ttyUSB0" #may be different for you
How can I scan and find the Arduino, and know to what port I should connect to automatically?
(I have OSX)
Thanks!
This can be tricky to do in a general way, because Arduino devices appear as USB serial ports, making it hard to distinguish between Arduino and non-Arduino ports.
The brute-force approach is: enumerate the USB serial devices, open() each in turn, and see if your firmware boot header is sent on the other end. On OSX, the USB serial devices are at /dev/tty.*, but that may change with future OS updates. This method works, but can be slow and timing sensitive. I've found that a startup delay on the Arduino before sending a header helps, as well as a simple "hello, are you there?" command the host can use to bang for signs of life.
Also, you can save the last port found so that subsequent app launches try that port first.
A variant: if your app asks the user to plug in the Arduino at startup, you can list the USB ports in /dev, wait for user to confirm it's plugged in, and list the ports again. Any newly appearing device is likely your Arduino.
At the next level, you could look at the USB Vendor and Product IDs (VID & PID). However, these IDs are all over the map in Arduino-land. They differ by model, version, revision, Chinese clones, and the various Arduino-compatible devices. See this writeup at Adafruit.
If you're just trying to make things work with a very narrow hardware set (e.g. the one Arduino on your bench), you can use this OSX command to see the USB device details:
system_profiler SPUSBDataType
With my system, I get:
...
USB Bus:
Host Controller Location: Built-in USB
Host Controller Driver: AppleUSBUHCI
PCI Device ID: 0x7fff000027c9
PCI Revision ID: 0x7fff00000002
PCI Vendor ID: 0x7fff00008086
Bus Number: 0x3d
Communication Device:
Product ID: 0x0043
Vendor ID: 0x2341
Version: 0.01
Serial Number: 75331313133351800000
Speed: Up to 12 Mb/sec
Manufacturer: Arduino (www.arduino.cc)
Location ID: 0x3d100000 / 2
Current Available (mA): 500
Current Required (mA): 100
The location ID (0x3d100000 / 2) seems to match up with the device name: /dev/cu.usbmodem3d11
See this question for running command line commands from within a Ruby script.