Serial connection 128000 Baud

The place to post if you need help or advice

Moderators: ChriThor, LXF moderators

Serial connection 128000 Baud

Postby uli » Fri May 03, 2013 10:43 am

Hi all,

I own a charger (iCharger 206B from Junsi) which has a USB interface (internally working with a CP210x chip form Silicon Laboratories). The baud rate is fixed to 128000 Baud and this seems to be a problem for Linux (non standard baudrate).

Windows on the other hand supports this with no problem at all.

Is there a way to get a 128000 baudrate in linux? When I try for example moserial and set the baud rate to 128000 baud it just crashes a few seconds later.

Using picocom from the terminal gives me a little more information about the problem:

FATAL: failed to add device /dev/ttyS0: Invalid baud rate

When searching for a explanation or solution, I found some pointers but no information on how to solve this problem ( it seems there was a bug filed at suse in 2010: http://lists.opensuse.org/opensuse-bugs/2010-04/msg03125.html ).

I use Ubuntu 12.10

Any ideas?

Thanks

Uli



[url][/url]
uli
 
Posts: 3
Joined: Thu May 02, 2013 7:42 pm

Postby Bazza » Mon May 06, 2013 6:00 pm

First things first...

Why are you attempting to hit /dev/ttyS0?

As you are on a USB slot the the device will probably be /dev/ttyUSBx OR /dev/ttyACMx whre x = 0 to 7.

How to find what it is:-
(Assumptions; you are in a Linux, root mode terminal, etc.)
1) Ensure the device is disconnected...
2) ls /dev/*tty*
3) Connect the device and allow a few seconds to settle.
4) ls /dev/*tty*
5) Scroll the terminal to see the diff's...

These will be the device name(s) added.

Let us assume that at least one is /dev/ttyUSB0

Try this from the terminal:-

*****$ stty -F /dev/ttyUSB0 128000<CR>
*****$ stty -F /dev/ttyUSB0 raw<CR>
*****$ stty<CR>

The last one should give the parameters only IF it works...

It is a long shot but worth a try...
73...

Bazza, G0LCU...

Team AMIGA...

The less that I speak, the smarter I sound.
User avatar
Bazza
LXF regular
 
Posts: 1565
Joined: Sat Mar 21, 2009 11:16 am
Location: Loughborough

Postby nelz » Mon May 06, 2013 6:29 pm

Bazza wrote:How to find what it is:-
(Assumptions; you are in a Linux, root mode terminal, etc.)
1) Ensure the device is disconnected...
2) ls /dev/*tty*
3) Connect the device and allow a few seconds to settle.
4) ls /dev/*tty*
5) Scroll the terminal to see the diff's...


Or
1) Ensure the device is disconnected...
2) Run "tail -f /var/log/messages | grep /dev/"
3) connect the device

You can also use "dmesg --follow" instead of "tail -f /var/log/messages" but only with the most recent versions of dmesg.
"Insanity: doing the same thing over and over again and expecting different results." (Albert Einstein)
User avatar
nelz
Site admin
 
Posts: 8964
Joined: Mon Apr 04, 2005 11:52 am
Location: Warrington, UK

Serial connection 128000 Baud

Postby uli » Thu May 09, 2013 10:52 am

sorry I did a mistake in my initial post, I meant of course /dev/ttyUSB0 and yes when I plug the charger in I can see that it is available as ttyUSB0:

[ 44.411946] usbcore: registered new interface driver usbserial
[ 44.411966] USB Serial support registered for generic
[ 44.460610] usbcore: registered new interface driver usbserial_generic
[ 44.460616] usbserial: USB Serial Driver core
[ 44.462330] USB Serial support registered for cp210x
[ 44.462393] cp210x 4-2:1.0: cp210x converter detected
[ 44.636098] usb 4-2: reset full-speed USB device number 2 using ohci_hcd
[ 44.845288] usb 4-2: cp210x converter now attached to ttyUSB0
[ 44.845316] usbcore: registered new interface driver cp210x
[ 44.845319] cp210x: v0.09:Silicon Labs CP210x RS232 serial adaptor driver

But still it doesn't work as expected:

uli@uli-MacBookAir:~$ picocom -b 128000 /dev/ttyUSB0
picocom v1.4

port is : /dev/ttyUSB0
flowcontrol : none
baudrate is : 128000
parity is : none
databits are : 8
escape is : C-a
noinit is : no
noreset is : no
nolock is : no
send_cmd is : ascii_xfr -s -v -l10
receive_cmd is : rz -vv


FATAL: failed to add device /dev/ttyUSB0: Invalid baud rate
uli@uli-MacBookAir:~$ stty -F /dev/ttyUSB0 128000
stty: invalid argument `128000'
Try `stty --help' for more information.

or as suggested:


uli@uli-MacBookAir:~$ picocom -b 128000 /dev/ttyUSB0
picocom v1.4

port is : /dev/ttyUSB0
flowcontrol : none
baudrate is : 128000
parity is : none
databits are : 8
escape is : C-a
noinit is : no
noreset is : no
nolock is : no
send_cmd is : ascii_xfr -s -v -l10
receive_cmd is : rz -vv

uli@uli-MacBookAir:~$ stty -F /dev/ttyUSB0 128000
stty: invalid argument `128000'
Try `stty --help' for more information.


uli@uli-MacBookAir:~$ stty -F /dev/ttyUSB0 raw
uli@uli-MacBookAir:~$ stty
speed 38400 baud; line = 0;
eol = M-^?; eol2 = M-^?; swtch = M-^?;
ixany iutf8



Uli
uli
 
Posts: 3
Joined: Thu May 02, 2013 7:42 pm

Postby ferrari » Fri May 10, 2013 9:02 am

You might want to consider purchasing an in-line baud rate converter instead. I've seen a few that support the baud rate you desire.
ferrari
LXF regular
 
Posts: 174
Joined: Tue May 03, 2005 11:09 am

Postby uli » Sat May 11, 2013 12:00 pm

Yes I could do that, or use a Microcontroller to do that, but I really dislike the fact that Linux isn't able to handle this serial speed even if it is technical possible and needed from the user standpoint.

And even worse M$ can handle these settings with no problem at all.

Uli
uli
 
Posts: 3
Joined: Thu May 02, 2013 7:42 pm

Postby ferrari » Mon May 13, 2013 4:33 am

I guess the need for it is minimal... most equipment default to standard baud rates. (I've never encountered the situation you describe).
ferrari
LXF regular
 
Posts: 174
Joined: Tue May 03, 2005 11:09 am

Re: Serial connection 128000 Baud

Postby ewykh » Mon Jun 24, 2013 9:53 am

uli wrote:I own a charger (iCharger 206B from Junsi) which has a USB interface (internally working with a CP210x chip form Silicon Laboratories). The baud rate is fixed to 128000 Baud and this seems to be a problem for Linux (non standard baudrate).

You could of course petition Junsi to release a trivial firmware modification to change the 206B to use 115200 bps instead of 128000 bps...

As you know (since it works in Windows) your hardware is capable of handing 128000 bps; the problem is that getting a request for this speed through all the layers of library and kernel between an application program and the hardware would require changes to many different packages, and worse, changes to various standards. I can't see it happening unless there was a very popular product that needed it.

However, given Linux is open source, you can fairly easily do it yourself, and indeed I did it on my own system so that I could use that exact same model of battery charger!

I couldn't be bothered with all the changes that would have been needed to add proper support for B128000. Instead, what I did was to take over one of the existing speeds that I never used for anything else (I chose B230400), and then modified the cp210x.c kernel module source file so that when it was told to run at 230400 bps it actually used 128000 bps. The change to cp210x.c (from /usr/src/linux-source-3.5.0/drivers/usb/serial/cp210x.c) is quite trivial:

Code: Select all
--- cp210x.c.old        2013-06-24 19:15:56.721784737 +1000
+++ cp210x.c.new        2013-06-24 19:25:18.573803882 +1000
@@ -27,7 +27,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.09"
+#define DRIVER_VERSION "v0.09k128"
 #define DRIVER_DESC "Silicon Labs CP210x RS232 serial adaptor driver"
 
 /*
@@ -431,9 +431,7 @@
        else if (baud <= 64111)    baud = 64000;
        else if (baud <= 77608)    baud = 76800;
        else if (baud <= 117028)   baud = 115200;
-       else if (baud <= 129347)   baud = 128000;
-       else if (baud <= 156868)   baud = 153600;
-       else if (baud <= 237832)   baud = 230400;
+       else if (baud <= 237832)   baud = 128000;
        else if (baud <= 254234)   baud = 250000;
        else if (baud <= 273066)   baud = 256000;
        else if (baud <= 491520)   baud = 460800;

So now I just ask for 230400 bps and get 128000 bps, which works perfectly with the 206B charger.

By the way, if you don't want to rebuild an entire kernel, you can use DKMS. It is probably getting a bit off-topic, but (once you install all the necessary kernel source and development tool packages) you just create a directory (say /usr/src/cp210x-0.09k128) and put in it thee files: the patched cp210x.c, dkms.conf which looks like:
Code: Select all
PACKAGE_VERSION="0.09k128"

# Items below here should not have to change with each driver version
PACKAGE_NAME="cp210x"
MAKE[0]="make -C ${kernel_source_dir} SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
CLEAN="make -C ${kernel_source_dir} SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build clean"

BUILT_MODULE_NAME[0]="cp210x"
DEST_MODULE_LOCATION[0]="/kernel/drivers/usb/serial/"

and Makefile that looks like:
Code: Select all
#
# Makefile for the USB serial device drivers.
#

# Object file lists.

obj-m                   += cp210x.o

You can then build and install the module use the commands:
Code: Select all
dkms add -m cp210x -v 0.09k128
dkms build -m cp210x -v 0.09k128
dkms install -m cp210x -v 0.09k128

Finally, either reboot or else force a reload of the cp210x module so that you are using the new one:
Code: Select all
depmod -a
rmmod cp210x
modprobe cp210x

Note that you need to be logged in as root to do most of this.

By the way, I also added a udev rule (/etc/udev/rules.d/95-cp210x.rules) that looks like:
Code: Select all
BUS!="usb", ACTION!="add", SUBSYSTEM!=="usb_device", GOTO="kcontrol_rules_end"

ATTRS{idProduct}=="ea60", ATTRS{idVendor}=="10c4", ATTRS{product}=="Junsi iCharger 206B", MODE="664", GROUP="plugdev", SYMLINK+="ic206b"

LABEL="kcontrol_rules_end"
so that I can now refer to /dev/ic206b whenever I want to access this device.

Hope this helps!
ewykh
 
Posts: 2
Joined: Mon Jun 24, 2013 7:26 am
Location: Australia

Re: Serial connection 128000 Baud

Postby ewykh » Tue Jan 12, 2016 3:03 am

There is a very simple solution to this problem. All you need to do is to reprogram the iCharger 206B so that it uses 128000 bps when your Linux system asks for one of the standard rates (say 230400 bps).

First you need to install the Linux CP210x programmer from http://cp210x-program.sourceforge.net/ and either log in as root or else set up udev rules to allow a normal user to write to the 206B. If you get everything installed correctly then you can enter the command:
Code: Select all
./cp210x-program
and get back information about the current state of your 206B. In my case what I saw was:
Code: Select all
[usb device]
product_string = Junsi iCharger 206B
serial_number = 1011025059
product_id = 10C4
vendor_id = EA60
version = 1.00
bus_powered = no
max_power = 100
locked = no
part_number = 2
vendor_string = Silicon Labs

[baudrate table]
1500000 = FFF0, FFFA, 1 # 1500000 Baud, 12 us
1500000 = FFF0, FFFA, 1 # 1500000 Baud, 12 us
1200000 = FFEC, FFF8, 1 # 1200000 Baud, 16 us
 921600 = FFE6, FFF6, 1 #  923077 Baud, 20 us
 576000 = FFD6, FFF0, 1 #  571429 Baud, 32 us
 500000 = FFD0, FFEE, 1 #  500000 Baud, 36 us
 460800 = FFCC, FFEC, 1 #  461538 Baud, 40 us
 256000 = FFA2, FFDC, 1 #  255319 Baud, 72 us
 250000 = FFA0, FFDC, 1 #  250000 Baud, 72 us
 230400 = FF98, FFD9, 1 #  230769 Baud, 78 us
 153600 = FF64, FFC5, 1 #  153846 Baud, 118 us
 128000 = FF44, FFB9, 1 #  127660 Baud, 142 us
 115200 = FF30, FFB2, 1 #  115385 Baud, 156 us
  76800 = FEC8, FF8B, 1 #   76923 Baud, 234 us
  64000 = FE89, FF73, 1 #   64000 Baud, 282 us
  57600 = FE5F, FF63, 1 #   57554 Baud, 314 us
  56000 = FE53, FF5F, 1 #   55944 Baud, 322 us
  51200 = FE2B, FF50, 1 #   51173 Baud, 352 us
  38400 = FD8F, FF15, 1 #   38400 Baud, 470 us
  28800 = FCBF, FEC7, 1 #   28812 Baud, 626 us
  19200 = FB1E, FE2B, 1 #   19200 Baud, 938 us
  16000 = FA24, FE0C, 1 #   16000 Baud, 1.000 ms
  14400 = F97D, FE0C, 1 #   14397 Baud, 1.000 ms
   9600 = F63C, FE0C, 1 #    9600 Baud, 1.000 ms
   7200 = F2FB, FE0C, 1 #    7201 Baud, 1.000 ms
   4800 = EC78, FE0C, 1 #    4800 Baud, 1.000 ms
   4000 = E890, FE0C, 1 #    4000 Baud, 1.000 ms
   2400 = D8F0, FE0C, 1 #    2400 Baud, 1.000 ms
   1800 = CBEB, FE0C, 1 #    1800 Baud, 1.000 ms
   1200 = B1E0, FE0C, 1 #    1200 Baud, 1.000 ms
    600 = 63C0, FE0C, 1 #     600 Baud, 1.000 ms
    300 = B1E0, FE0C, 4 #     300 Baud, 1.000 ms

The commands you need are then:
Code: Select all
./cp210x-program -f ic206.eeprom.hex
./cp210x-program -p -F ic206.eeprom.hex -w --set-baudrate 230400:FF44,FFB9,1

The first line saves a copy of your original EEPROM into the file ic206.eeprom.hex, which is then used as a starting point to write a modified EEPROM with the 230400 bps entry changed to be 128000 bps instead. You can check it succeeded by running:
Code: Select all
./cp210x-program
again; the output should be the same as before except for the 230400 line, which should now look like:
Code: Select all
 230400 = FF44, FFB9, 1 #  127660 Baud, 142 us

After this, simply tell Linux to use speed 230400 bps, and you should be able to talk to the 206B at 128000 bps.

Works for me, anyway!

Hope this helps someone else...
ewykh
 
Posts: 2
Joined: Mon Jun 24, 2013 7:26 am
Location: Australia


Return to Help!

Who is online

Users browsing this forum: No registered users and 0 guests