Setting hardware flow control parameters in FreeBasic - flow-control

I'd appreciate advise on how to set the following hardware flow control parameters in FreeBasic
ControlHandShake=(DTR_HANDSHAKE, DSR_HANDSHAKE),
FlowReplace=(TRANSMIT_TOGGLE, RTS_HANDSHAKE),
XonLimit=4096,
XoffLimit=1024

Hardware and OS dependent.
MOST OS's have command line programs or scripts that will set your hardware up as you wish.
Easiest: use 'open pipe [command string]' or 'shell [command string]' to reprogram the device.
Example:
To talk to one of my arduino projects, I use:
PortStr = "COM12:9600,N,8,1,CD,CS,DS,OP,BIN"
shell "stty -F /dev/ttyUSB0 speed 9600 -clocal -hupcl"
sleep 1000
open com "/dev/ttyUSB0:9600,n,8,1,cs0,cd0,ds0,rs,bin" as #filnum
Way old days: you talked directly to the 16650 or other chip directly. peek/poke/etc.
David

Related

Sending files over Half-duplex interface

I'm trying to send files over a half-duplex interface (RS-485) between a box PC running debian (4.19) and a SBC with an im6xDL.
Thanks to this community I can successfully transfer simple data between the units using picocom or by echoing/reading.
The box PC supports half-duplex RS-485 natively and has automatic RTS functions so that you can read/send data without any issue. The SBC on the other hand needs to be toggled to change into RX or TX mode.
This turned out to be a problem when I tried to send files from the box PC to the SBC.
On the box PC:
picocom /dev/ttyUSB0 -b 9600 -fn
C-a,C-S
***file: /home/user/test.txt
Transfer incomplete
*** exit status: 128
On the SBC
picocom /dev/ttymxc2 -b 9600 -fn -et
C-a,C-r
Terminal ready
�000000
As you can see something is terribly wrong, it is like it cannot interpret the bits when a file is being transferred.
My questions:
Is it possible to send files from the command line in half-duplex systems? (The SBC needs to be in RX mode the entire time).
Is there another way to achieve this that is more intuitive?
As always, thanks for the help and support :)
/W
See here:
Pymodbus - Read input register of Energy meter over rs485 on uart of raspberry pi3
The solution I presented there using pylibmodbus should work for any hardware with UART and one or two GPIO lines accessible from user space in Linux.
If, on the other hand, what you want to do is use something like picocom or minicom then you can take a look at the hardware-only solution using a 555 timer.
Of course, if prototyping circuits is not for you, you can always buy a USB to RS485 with half-duplex support. You have many available but those based on the MAX13487 IC seem to work very well.
EDIT: The solution using the 555 timer is not in the post I linked above but here together with some more background material on half-duplex RS485 links: RS485: Inappropriate ioctl for device

Bi-directional sniffing/snooping on an ALSA MIDI SysEx exchange

Does anyone know of a good way to get a bi-directional dump of MIDI SysEx data on Linux? (between a Yamaha PSR-E413 MIDI keyboard and a copy of the Yamaha MusicSoft Downloader running in Wine)
I'd like to reverse-engineer the protocol used to copy MIDI files to and from my keyboard's internal memory and, to do that, I need to do some recording of valid exchanges between the two.
The utility does work in Wine (with a little nudging) but I don't want to have to rely on a cheap, un-scriptable app in Wine when I could be using a FUSE filesystem.
Here's the current state of things:
My keyboard connects to my PC via a built-in USB-MIDI bridge. USB dumpers/snoopers are a possibility, but I'd prefer to avoid them if possible. I don't want to have to decode yet another layer of protocol encoding before I even get started.
I run only Linux. However, if there really is no other option than a Windows-based dumper/snooper, I can try getting the USB 1.1 pass-through working on my WinXP VirtualBox VM.
I run bare ALSA for my audio system with dmix for waveform audio mixing.
If a sound server is necessary, I'm willing to experiment with JACK.
No PulseAudio please. It took long enough to excise it from my system.
If the process involves ALSA MIDI routing:
a virtual pass-through device I can select from inside the Downloader is preferred because it often only appears in an ALSA patch bay GUI like patchage an instant before it starts communicating with the keyboard.
Neither KMIDIMon nor GMIDIMonitor support snooping bi-directionally as far as I can tell.
virmidi isn't relevant and I haven't managed to get snd-seq-dummy working.
I I suppose I could patch ALSA to get dumps if I really must, but it's really an option of last resort.
The vast majority of my programming experience is in Python, PHP, Javascript, and shell script.
I have almost no experience programming in C.
I've never even seen a glimpse of kernel-mode code.
I'd prefer to keep my system stable and my uptime high.
This question has been unanswered for some time and while I do not have an exact answer to your problem I maybe have something that can push you in the right direction (or maybe others with similar problems).
I had a similar albeit less complex problem when I wanted to sniff the data used to set and read presets on an Akai LPK25 MIDI keyboard. Similar to your setup the software to setup the keyboard can run in Wine but I also had no luck in finding a sniffer setup for Linux.
For the lack of an existing solution I rolled my own using ALSA MIDI routing over virmidi ports. I understand why you see them as useless because without additional software they cannot help at sniffing MIDI traffic.
My solution was programming a MIDI relay/bridge in Java where I read input from a virmidi port, display the data and send it further to the keyboard. The answer from the keyboard (if any) is also read, displayed and finally transmitted back to the virmidi port. The application in Wine can be setup to use the virmidi port for communication and in theory this process is completely transparent (except for potential latency issues). The application is written in a generic way and not hardcoded to my problem.
I was only dealing with SysEx messages of about 20 bytes length so I am not sure how well the software works for sniffing the transfer of large amounts of data. But maybe you can modify it / write your own program following the example.
Sources available here: https://github.com/hiben/MIDISpy
(Java 1.6, ant build file included, source is under BSD license)
I like using aseqdump for that.
http://www.linuxcommand.org/man_pages/aseqdump1.html
You could use virtual midi devices for this purpose. So you have to load snd_seq_dummy so that it creates at least two ports:
$ sudo modprobe -r snd_seq_dummy
$ sudo modprobe snd_seq_dummy ports=1 duplex=1
Then you should have a device named Midi through:
$ aconnect -i -o -l
client 0: 'System' [type=kernel]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0:A'
1 'Midi Through Port-0:B'
client 131: 'VMPK Input' [type=user,pid=50369]
0 'in '
client 132: 'VMPK Output' [type=user,pid=50369]
0 'out '
I will take the port and device numbers form this example. You have to inspect them yourself according to your setup.
Now you plug your favourate MIDI Device to the Midi Through ports:
$ aconnect 132:0 14:0
$ aconnect 14:0 131:0
At this time you have a connection where you can spy on both devices at the same time. You could use aseqdump to spy the MIDI conversation. There are different possibilities. I suggest to spy the connection between the loopback devices and the real device. This allows you for rawmidi connections to the loopback devices.
$ aseqdump -p 14:0,132:0 | tee dump.log
Now everything is set up for use. You just have to be careful about port names in your MIDI application. It should read MIDI data from Midi Through Port-0:B and write data to Midi Through Port-0:B.
Some additional hint: You could use the graphical frontend patchage for connecting and inspecting the MIDI connections via drag and drop. If you do this you will see that every Midi Through port occurs twice once as input and once as output. Both have to be connected in order to make this setup work.
If you want to use GMidiMonitor or some other application you spy on both streams intermixed (without showing the direction) using aconnect suppose 129:0 is the Midi Monitor port :
$ aconnect 14:0 129:0
$ aconnect 132:0 129:0
If you want to have exact direction information you could add another GMidiMonitor instance that you connect only to one of the ports. The missing messages come from the other port.
What about using gmidimonitor? See http://home.gna.org/gmidimonitor/

How to open serial port in linux without changing any pin?

Posix requires changing RTS pin on port opening. I want a way to avoid it.
I have no idea why you'd want to do this, but this can be done pretty easily by modifying the linux kernel driver for your serial console so it doesn't toggle RTS. For example, for the 8250-series driver in drivers/tty/serial/8250/ you could change every write to the MCR register (UART_MCR) to ensure that bit 1 (mask is UART_MCR_RTS) is never set.
Since it's abstracted away in userspace, you're out of luck if you want to do this without modifying the kernel driver.
Having the same problem, I'd give it a try by patching the ftdi_sio kernel driver. You just need to uncomment a small piece of code in ftdi_dtr_rts() like this:
static void ftdi_dtr_rts(struct usb_serial_port *port, int on) {
...
/* drop RTS and DTR */
if (on)
set_mctrl(port, TIOCM_DTR /*| TIOCM_RTS*/); // <<-- HERE
else
clear_mctrl(port, TIOCM_DTR /*| TIOCM_RTS*/); // <<-- and HERE
}
and the RTS handshake line is not longer changed upon open() call.
Note, that the uart than might not longer working with RTS/CTS hardware handshake, as long as your modified kernel driver is loaded. But you can still control the state of the RTS handshake line manually by calling e.g.:
int opins = TIOCM_RTS;
ioctl(tty_fd, TIOCMBIC, &opins);
I'd tested this with the Ctrl+A+G command of picocom 2.3a, running Kubuntu 16.04 64 bit and Ftdi FT2232H based usb uart adapter.
You might find more details on this topic here.
A change in the DTR pin can be (eventually) avoided using the command line
stty -F /dev/ttyUSB0 -hupcl
This has the effect of making DTR turn on; and subsequently when the port is opened and closed, DTR is not affected.
Source: https://raspberrypi.stackexchange.com/questions/9695/disable-dtr-on-ttyusb0/27706#27706
And there is code there to do the same thing from python via termios, this can be done before opening the port via pyserial:
import termios
path = '/dev/ttyACM0'
# Disable reset after hangup
with open(path) as f:
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
The OP was running this on a Raspberry Pi, but I just tried it on Linux Mint on x86_64, it worked. I don't know how RTS is affected.
The reason I find this useful, is for communication with an Arduino Nano - which has a USB-> serial chip on board - and normally the Arduino gets reset every time you open the serial port from linux (rising edge of DTR causes reset). For some applications, this is not a problem, but it's clearly useful to avoid this for other applications, and it's not so easy to remove that tiny capacitor from the Arduino which connects DTR to reset.
You will still get a single reset when the stty command is executed (after plugging in the USB cable). But at least you can then keep opening and closing the serial port after that without further resets.
calling fopen("/dev/ACM0", "r") doesn't require you do do anything:) You may not receive the data you expect though.

Controlling a USB power supply (on/off) with Linux

Is it possible to turn on/off power supplies from USB manually with Linux?
There's this external USB cooling fan (the kind you use to cool yourself off, not the PC), and it would be nice to be able to control it from the terminal, because I want to position the fan somewhere far away.
I suppose this could also be useful for a variety of other things as well, because there's a lot of USB toys out there. Maybe air purifiers, etc. (I heard they don't really work though).
According to the docs, there were several changes to the USB power management from kernels 2.6.32, which seem to settle in 2.6.38. Now you'll need to wait for the device to become idle, which is governed by the particular device driver. The driver needs to support it, otherwise the device will never reach this state. Unluckily, now the user has no chance to force this. However, if you're lucky and your device can become idle, then to turn this off you need to:
echo "0" > "/sys/bus/usb/devices/usbX/power/autosuspend"
echo "auto" > "/sys/bus/usb/devices/usbX/power/level"
or, for kernels around 2.6.38 and above:
echo "0" > "/sys/bus/usb/devices/usbX/power/autosuspend_delay_ms"
echo "auto" > "/sys/bus/usb/devices/usbX/power/control"
This literally means, go suspend at the moment the device becomes idle.
So unless your fan is something "intelligent" that can be seen as a device and controlled by a driver, you probably won't have much luck on current kernels.
Note. The information in this answer is relevant for the older kernels (up to 2.6.32). See tlwhitec's answer for the information on the newer kernels.
# disable external wake-up; do this only once
echo disabled > /sys/bus/usb/devices/usb1/power/wakeup
echo on > /sys/bus/usb/devices/usb1/power/level # turn on
echo suspend > /sys/bus/usb/devices/usb1/power/level # turn off
(You may need to change usb1 to usb n)
Source: Documentation/usb/power-management.txt.gz
PowerTOP from Intel allows you to toggle devices such as usb peripherals in real-time. These are called 'tunables'.
sudo apt install powertop
sudo powertop
Tab over to 'tunables'.
Scroll down to your device.
Hit enter to toggle power saving mode (Good/Bad)
Note that Bad means the device is always on. Toggling to Good will turn off the device after the preset inactive saving time (default is 2000ms).
See the PowerTOP docs for details on how to make these changes permanent.It generates the config scripts for you (pretty much as described by other posters on this thread).
NOTE: These scripts do not affect USB pin power (which is always on).
These only send the driver protocol to activate and deactivate a device.
If you want to control pin power, you could use either a supported smart USB hub, or better yet a microcontroller.
I have found these solutions that at least work for properly configured Terminus FE 1.1 USB hub chip:
1.To turn off power on all USB ports of a hub, you may unbind the hub from kernel using:
echo "1-4.4.4" > /sys/bus/usb/drivers/usb/unbind
to turn power back on - you may bind it back using
echo "1-4.4.4" > /sys/bus/usb/drivers/usb/bind
2.Switching power at each port individually is trickier: I was able to use hubpower to control each port - but it comes with a downside: hubpower first disconnects the usbdevfs wich causes all of the USB devices to disconect from system, at least on ubuntu:
usb_ioctl.ioctl_code = USBDEVFS_DISCONNECT;
rc = ioctl(fd, USBDEVFS_IOCTL, &usb_ioctl);
With this ioctl disabled I was able to switch off individual port power without detaching all devices - but the power goes back on immediately (probably due to kernel seeing an uninitialized device) which causes USB device just to do a "cold restart" which is what I generally wanted to do. My patched hubpower is here
You could use my tool uhubctl to control USB power per port for compatible USB hubs.
I wanted to do this, and with my USB hardware I couldn't. I wrote a hacky way how to do it here:
http://pintant.cat/2012/05/12/power-off-usb-device/ .
In a short way: I used a USB relay to open/close the VCC of another USB cable...
echo '2-1' |sudo tee /sys/bus/usb/drivers/usb/unbind
works for ubuntu
The reason why folks post questions such as this is due to the dreaded- indeed "EVIL"- USB Auto-Suspend "feature".
Auto suspend winds-down the power to an "idle" USB device and unless the device's driver supports this feature correctly, the device can become uncontactable. So powering a USB port on/off is a symptom of the problem, not the problem in itself.
I'll show you how to GLOBALLY disable auto-suspend, negating the need to manually toggle the USB ports on & off:
Short Answer:
You do NOT need to edit "autosuspend_delay_ms" individually: USB autosuspend can be disabled globally and PERSISTENTLY using the following commands:
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="/&usbcore.autosuspend=-1 /' /etc/default/grub
update-grub
systemctl reboot
An Ubuntu 18.04 screen-grab follows at the end of the "Long Answer" illustrating how my results were achieved.
Long Answer:
It's true that the USB Power Management Kernel Documentation states autosuspend is to be deprecated and in in its' place "autosuspend_delay_ms" used to disable USB autosuspend:
"In 2.6.38 the "autosuspend" file will be deprecated
and replaced by the "autosuspend_delay_ms" file."
HOWEVER my testing reveals that setting usbcore.autosuspend=-1 in /etc/default/grub as below can be used as a GLOBAL toggle for USB autosuspend functionality- you do NOT need to edit individual "autosuspend_delay_ms" files.
The same document linked above states a value of "0" is ENABLED and a negative value is DISABLED:
power/autosuspend_delay_ms
<snip> 0 means to autosuspend
as soon as the device becomes idle, and negative
values mean never to autosuspend. You can write a
number to the file to change the autosuspend
idle-delay time.
In the annotated Ubuntu 18.04 screen-grab below illustrating how my results were achieved (and reproducible), please remark the default is "0" (enabled) in autosuspend_delay_ms.
Then note that after ONLY setting usbcore.autosuspend=-1 in Grub, these values are now negative (disabled) after reboot. This will save me the bother of editing individual values and can now script disabling USB autosuspend.
Hope this makes disabling USB autosuspend a little easier and more scriptable-
I had a problem when connecting my android phone, I couldn't charge my phone because the power switch on and then off ...
PowerTop let me find this setting and was useful to fix the issue ( auto value was causing issue):
echo 'on' | sudo tee /sys/bus/usb/devices/1-1/power/control
USB 5v power is always on (even when the computer is turned off, on some computers and on some ports.) You will probably need to program an Arduino with some sort of switch, and control it via Serial library from USB plugged in to the computer.
In other words, a combination of this switch tutorial and this tutorial on communicating via Serial libary to Arduino plugged in via USB.
So far I came to the conclusion that you cannot control the power of a USB port. The 5V USB is always provided, and it's up to the device to use it or not. You can check this with a 5V fan or light.
I've tried various methods (disconnect/reconnect/bind/unbind/reset signal). Best so far are bind/unbind as it forces a cold restart of the device (but no power cycle).
I came up with a solution to reset USB devices, ports and controllers in a python script, which supports all of the above methods.
You can find the script at my Github page
Usage:
usb_reset.py -d 8086:1001 --reset-hub
The script uses among others the following solution to reset USB hubs/controllers:
Unbindind a USB port / controller works best via:
echo "myhub" > "/sys/bus/usb/drivers/usb/unbind"
echo "myhub" > "/sys/bus/usb/drivers/usb/bind"
Where myhub is found in /sys/bus/usb/devices/*
Or litteral controllers:
echo "mycontroller" > "/sys/bus/pci/drivers/unbind"
echo "mycontroller" > "/sys/bus/pci/drivers/bind"
Where mycontroller is found in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*

How can I monitor data on a serial port in Linux?

I'm debugging communications with a serial device, and I need to see all the data flowing both directions.
It seems like this should be easy on Linux, where the serial port is represented by a file. Is there some way that I can do a sort of "bi-directional tee", where I tell my program to connect to a pipe that copies the data to a file and also shuffles it to/from the actual serial port device?
I think I might even know how to write such a beast, but it seems non-trivial, especially to get all of the ioctls passed through for port configuration, etc.
Has anyone already built such a thing? It seems too useful (for people debugging serial device drivers) not to exist already.
strace is very useful for this. You have a visualisation of all ioctl calls, with the corresponding structure decoded. The following options seems particularly useful in your case:
-e read=set
Perform a full hexadecimal and ASCII dump of all the data read from
file descriptors listed in the
specified set. For example, to see all
input activity on file descriptors 3
and 5 use -e read=3,5. Note that this
is independent from the normal tracing
of the read(2) system call which is
controlled by the option -e
trace=read.
-e write=set
Perform a full hexadecimal and ASCII
dump of all the data written to file
descriptors listed in the specified
set. For example, to see all output
activity on file descriptors 3 and 5
use -e write=3,5. Note that this is
independent from the normal tracing of
the write(2) system call which is
controlled by the option -e
trace=write.
I have found pyserial to be quite usable, so if you're into Python it shouldn't be too hard to write such a thing.
A simple method would be to write an application which opened
the master side of a pty and the tty under test. You would then
pass your tty application the slave side of the pty as the 'tty device'.
You would have to monitor the pty attributes with tcgetattr() on the pty
master and call tcsetattr() on the real tty, if the attributes changed.
The rest would be a simple select() on both fd's copying data bi-directionally and copying it to a log.
I looked at a lot of serial sniffers. All of them are based on the idea of making a virtual serial port and sniff data from that port. However, any baud/parity/flow changes will break connection.
So, I wrote my own sniffer :). Most of the serial ports now are just USB-to-serial converters. My sniffer collects data from USB through debugfs, parse it and output to the console. Also any baudrate changes, flow control, line events, and serial errors are also recorded. The project is in the early stage of development and for now, only FTDI is supported.
http://code.google.com/p/uscmon/
Much like #MBR, I was looking into serial sniffers, but the ptys broke the parity check. However, his sniffer was not helping me, as I'm using a CP2102, and not a FT232. So I wrote my own sniffer, by following this, and now I have one that can record file I/O on arbitrary files: I called it tracie.

Resources