I would like to control some physical engines, switches on/off, lights through a self written C API.
I already have a very general overview of how to achieve this:
Use the kernels abstraction, write a driver on it and use this as control. The driver itself has to manage incoming bytes and interpret them (depends on port).
I personally would prefer to use a USB port because I can use my MacBook to develope.
But I know that the protocol is quite complicated. However here are my specific questions:
Which port is good to use (is USB a suitable option?)
Could I simply wire a engine to the USBs power cables and connect the data cables to a power swith or do I require an extra board?
Are there better docs for OS X, BSD or gnu/Linux?
Bodo
To control physical engines, you have to add at least a power supply board, there is no way that your USB port drive a DC motor (maybe a LED).
The easiest I/O port on a computer is the LPT (parallel port), but this is a 'very' old thing. I agree that USB port is most convenient but in order to work easily with it I advise you to buy a small card.
This Usb board (or anything of the same kind) can do the trick.
I hope it could help you,
Related
I have a costume board with Xilinx Zynq UltraScale+ RFSoC.
I'm using 3 PS_GTR transceivers as sgmii.
2 of them are connected to external Marvell phy and the third connects directly (fixed link - without phy).
In the manufacturing stage i would like to make sure that the direct sgmii interface is assembled correctly - so I made an external loopback between tx and rx sgmii signals.
Now, Is it possible to transmit something through this external loopback and compare with the received data?
Is it possible to ping with yourself? (simple ping command not working: "ping -I eth2 ")
perhaps there is a 'patch' under the 'macb' kernel driver that someone can guide me through?
Thank you all,
Tzipi Kluska
Yes it is possible to ping yourself. Note that linux does or at least used to bypass the hardware when talking to itself and would do the loopback in the IP stack. I recently saw someone within a terminal (window, command line) isolate one network interface, then another another network interface and then it was trivial to use stock tools like ping and iperf to test the link.
Before doing that though, the serdes on your part should have PRBS capabilities (for a reason), some may have internal scope like features that allow you to extract an eye or at least numbers that indicate the quality of the eye. The marvell phy should also have this capability and you can both use a loopback to talk to yourself use various prbs lengths to check the quality of the link (less than one error in so many 10 to the 14th bits or whatever your desired quality is), and then when connected to the marvell repeat that.
Before doing all of this the software is often the hard part and you need to insure you have it working first, so you may wish to do loopbacks inside the fpga that do not have analog issues and get the software worked out, then in the serdes on the edge of the fpga they may have loopbacks in both directions, the marvell as well may have loopbacks in both directions so you can for example go direct fpga to marvell one is the tx and one the rx and vice versa, or you might enable a lan side shallow loopback on the marvell and talk to yourself.
Also depending on these speeds, hand made loopbacks might be noisy so sometimes a pcb based loopback (which also has to be designed) may wish to be deployed.
Can you ping yourself, absolutely. You can use other low level network interfaces like sockets, to make raw packets and talk to yourself through these interfaces as well. Ping, doing a ping flood, iperf, netperf, etc are all fine ways to exercise or get a warm fuzzy about the interface during both development and manufacture test.
Being an fpga you can of course have a test design that you load into the fpga that pushes the external interfaces and reports the bit error rate.
I am upgrading the processor in an embedded system for work. This is all in C, with no OS. Part of that upgrade includes migrating the processor-PC communications interface from IEEE-488 to USB. I finally got the USB firmware written, and have been testing it. It was going great until I tried to push through lots of data only to discover my USB connection is slower than the old IEEE-488 connection. I have the USB device enumerating as a CDC device with a baud rate of 115200 bps, but it is clear that I am not even reaching that throughput, and I thought that number was a dummy value that is a holdover from RS232 days, but I might be wrong. I control every aspect of this from the front end on the PC to the firmware on the embedded system.
I am assuming my issue is how I write to the USB on the embedded system side. Right now my USB_Write function is run in free time, and is just a while loop that writes one char to the USB port until the write buffer is empty. Is there a more efficient way to do this?
One of my concerns that I have, is that in the old system we had a board in the system dedicated to communications. The CPU would just write data across a bus to this board, and it would handle communications, which means that the CPU didn't have to waste free time handling the actual communications, but could offload the communications to a "co processor" (not a CPU but functionally the same here). Even with this concern though I figured I should be getting faster speeds given that full speed USB is on the order of MB/s while IEEE-488 is on the order of kB/s.
In short is this more likely a fundamental system constraint or a software optimization issue?
I thought that number was a dummy value that is a holdover from RS232 days, but I might be wrong.
You are correct, the baud number is a dummy value. If you create a CDC/RS232 adapter you would use this to configure your RS232 hardware, in this case it means nothing.
Is there a more efficient way to do this?
Absolutely! You should be writing chunks of data the same size as your USB endpoint for maximum transfer speed. Depending on the device you are using your stream of single byte writes may be gathered into a single packet before sending but from my experience (and your results) this is unlikely.
Depending on your latency requirements you can stick in a circular buffer and only issue data from it to the USB_Write function when you have ENDPOINT_SZ number of byes. If this results in excessive latency or your interface is not always communicating you may want to implement Nagles algorithm.
One of my concerns that I have, is that in the old system we had a board in the system dedicated to communications.
The NXP part you mentioned in the comments is without a doubt fast enough to saturate a USB full speed connection.
In short is this more likely a fundamental system constraint or a software optimization issue?
I would consider this a software design issue rather than an optimisation one, but no, it is unlikely you are fundamentally stuck.
Do take care to figure out exactly what sort of USB connection you are using though, if you are using USB 1.1 you will be limited to 64KB/s, USB 2.0 full speed you will be limited to 512KB/s. If you require higher throughput you should migrate to using a separate bulk endpoint for the data transfer.
I would recommend reading through the USB made simple site to get a good overview of the various USB speeds and their capabilities.
One final issue, vendor CDC libraries are not always the best and implementations of the CDC standard can vary. You can theoretically get more data through a CDC endpoint by using larger endpoints, I have seen this bring host side drivers to their knees though - if you go this route create a custom driver using bulk endpoints.
Try testing your device on multiple systems, you may find you get quite different results between windows and linux. This will help to point the finger at the host end.
And finally, make sure you are doing big buffered reads on the host side, USB will stop transferring data once the host side buffers are full.
I couldn't think of a better title name, but to the point.
I wanted to know how the wireless NIC/NIC operates with the system it is connected to (not over a connection, but an internal one or a pci, or usb, or any other peripheral), and what can the card itself do with the system (besides connecting to some router or AP, or anything not dealing with the hardware internals), or what it can communicate to the local system?
I'm not sure if these are defined at the assembly level or in the user-space level, so I would also like to know that as well, if possible.
External wireless NICs attach over USB; internal ones typically use PCI or PCIe.
The details of how these devices communicate with the host are all device-specific. In many cases, the NIC runs a firmware which the host must upload to the device at startup. The details of what this firmware must contain are basically never documented. A few wireless NICs (typically the older ones) actually implement hardware commands to perform operations like associating with an AP, but most do not.
There are no standards here. Every device is a little bit different. There is also almost never any documentation. If you want to learn more, your best bet is to find the source code for a Linux driver for the device you're interested in, dig into it, and hope it's well-commented.
I have a dsPIC33 with ECAN and wish to establish a protocol (using SDO if possible) in such way that it communicate between terminal software and dsPIC33 where I can perform diagnostics within dsPIC33 and supporting ICs.
I do not know what is required, so what is a low cost way of doing this? I could use a CAN-to-USB device, but I am unsure if this will work. What kind of protocol inside CANUSB wraps around the ASCII-based message?
What hardware can I use? Can it be used to monitor the CAN bus as well? I do not wish to invest in an expensive setup as in Vector or similar heavy-weight solution.
When you purchase CAN interface hardware, it does not typically include software to work with specific upper-level CAN protocols (like CANopen). They do usually come with a set of DLL files that allow you to write custom PC applications to interface with your hardware.
If you do not want to purchase any third-party software, then you must:
Implement a basic CAN driver for the dsPIC33 (transmit and receive a basic frame).
Implement the CANopen SDO protocol on top of your basic driver on the dsPIC33.
Purchase a low-cost CAN<->USB interface (which should come with DLLs that allow you to develop in C, C++ or C#.
Write a PC application using the DLL files which implements the CANopen SDO protocol.
You may want to look for open-source implementations of the protocol. One such implementation is CanFestival. However, I have never used this library.
You can download an open source project for CANopen from DATALINK ENGINEERING as this seems to be just what you need.
I am doing IO programming in C in Ubuntu. And I need the base address of the port to write data.
My laptop dont have a parallel port. So I bought a USB to Parallel port connector. I plugged in the device and its getting detected in /dev/usb/lp0
I ran "lsusb" to see the list of devices and I can see the ID also. But how can I get the base address ? For the usual hardware parallel devices, the base address is 0x0378. this address is not getting detected while using USB to Parallel device.
Please help.
A USB parallel port doesn't have a base address - it's not a meaningful concept for USB. I'm afraid the days of doing I/O on PC hardware via in and out instructions ended a few years ago, though lots of old tutorials still survive on the web.
You can write bytes to the parallel port as a character device, and these will appear on the printer port pins. The USB adapter will expect the other end to handshake data exactly like a printer. If you want to do general I/O prototyping, you're probably better off with a simple USB microcontroller like an Arduino.
Further discussion here.
If you are still interested to use this USB-to-parallel-printer device for your own bit-banging, it's important to know that their built-in firmware always allows controlling of D0..D7, INIT (as outputs), /ERR, ONL, PE (as inputs), but never for /ACK, BUSY (inputs), /STB, /AF, /SEL (outputs) pins.
And you need an 8-bit latch (e.g. 74HCT574) for catching data while strobing.
See here (https://www-user.tu-chemnitz.de/~ygu/bastelecke/PC/USB2LPT/faq#DIY)
especially for possible data rates.
Accessing from software side is a bit complicated but possible, and you may have to re-structure your software and hardware for making such adapters useable. I don't know for Linux case how to access, but IMHO you don't need to write a kernel-mode driver.