changeset 962:f4da3071dd61

doc/High-speed-serial write-up and Linux kernel patch added
author Mychaela Falconia <falcon@ivan.Harhan.ORG>
date Fri, 06 Nov 2015 21:46:05 +0000
parents 813287f7169c
children d69d1e097b18
files doc/High-speed-serial doc/linux-2.6.37.6-ftdi_sio.c.patch
diffstat 2 files changed, 140 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/High-speed-serial	Fri Nov 06 21:46:05 2015 +0000
@@ -0,0 +1,111 @@
+The highest baud rate supported by "standard" PC serial ports is 115200 bps,
+but Calypso UARTs can go quite a bit faster.  Being clocked with 13 MHz (a
+standard frequency in the GSM world), these UARTs can produce non-standard
+(outside of the GSM world) baud rates of 203125, 406250 and 812500 bps.  When
+working with Motorola C1xx and Openmoko GTA01/02 phones which present a debug
+and programming serial interface on a 2.5 mm headset jack, one can make use of
+these high serial baud rates by using a USB to headset jack programming cable
+based on one of the better USB-serial chips that can support these GSM special
+baud rates well above 115200.  The two USB-serial chips that are known to work
+in this manner are CP2102 and FTDI, although each of the two requires its own
+special quirks described below.  Other USB to serial cables use chips which
+don't support the high baud rates in question, and therefore are limited to
+115200 baud max like a "standard" PC serial port.
+
+FreeCalypso tools can use these high serial baud rates in the following ways:
+
+* When you use fc-loadtool to dump and program GSM device flash memory
+  (flashing firmware images), the transfers get annoyingly slow at 115200 baud
+  if you have to do it a lot.  Switching to 406250 or even better 812500 baud
+  makes them go considerably faster.
+
+* Some of our target devices have large enough RAM to execute a GSM firmware
+  image entirely from RAM without flashing - very handy for development and
+  experimentation.  The tool used to run these RAM-based images is fc-xram,
+  and it also supports the option of using high serial baud rates for the image
+  transfer for the same reason: repeatedly transferring 1.5 MiB images over
+  115200 baud gets tiresome.
+
+* If you are building your own GSM firmware (either FC GSM fw or one of our
+  TCS211-based hacks), you can make it run its RVTMUX interface at 406250 or
+  812500 baud.  We used this trick when we tried to make TCS211 with D-Sample-
+  targeting UI (176x220 pix LCD, 16 bits per pixel) send its virtual LCD raster
+  blits out the serial port.  Our rvtdump and rvinterf utilities support this
+  mode of operation by providing options to select different baud rates.
+
+Using CP2102 adapters
+=====================
+
+CP2102 chips have a built-in EEPROM that contains (among other things) a
+32-entry table in which the supported serial baud rates are programmed.  In
+order to support the special GSM baud rates, these rates need to be added to
+that table, displacing some other entries.  The convention established by the
+Pirelli DP-L10 phone (has a CP2102 built in and programmed at the factory for
+GSM baud rates) is that 203120 baud takes the place of 230400, 406250 takes the
+place of 460800, and 812500 takes the place of 921600.
+
+Because you need a special cable anyway to make the necessary physical
+connection to the debug/programming serial port presented on a 2.5 mm headset
+jack, you will probably be buying the requisite cable from a specialized
+professional vendor.  In that case it is that vendor's responsibility to sell
+you the cable with the CP2102 chip already programmed with GSM baud rates:
+because the physical construction of the cable (2.5 mm headset jack on the
+serial end) makes it specific to GSM devices, and all known GSM devices use a
+13 MHz clock or some integer multiple thereof, it is pointless for a
+physically-GSM-specific cable to be set up for 230400/460800/921600 baud when
+all known GSM devices will need 203125/406250/812500 baud instead.
+
+If you making a CP2102-based serial cable yourself (either for your own personal
+use or professionally/commercially), please follow these instructions for baud
+rate programming:
+
+http://bb.osmocom.org/trac/wiki/Hardware/CP210xTutorial
+
+If you follow the procedure given on that page, your CP2102 will be programmed
+the same way as the one in the Pirelli DP-L10 (Foxconn's original factory
+programming).
+
+The serial port handling code in FreeCalypso host tools is written to request
+B230400 from termios when 203125 baud is desired, likewise B460800 for 406250
+baud and B921600 for 812500 baud.  Therefore, if you have a CP2102-based cable
+with properly programmed EEPROM, everything will Just Work.
+
+Using FTDI adapters
+===================
+
+Unlike CP2102, FTDI adapters don't require any non-volatile EEPROM programming
+for GSM baud rates, but they have a different pain point - arguably a worse one
+- that is entirely a software issue.  The API which the Linux kernel provides
+to userspace applications for opening and configuring serial ports provides no
+clean, sensible way for an application to request a particular baud rate that
+is not in the predefined-once-and-for-all list, and to make it unambiguous to
+the in-kernel driver exactly what it wants.
+
+The method provided by the ftdi_sio driver in the standard Linux kernel is
+gross, and I (Space Falcon) refuse to use it.  The serial port handling code in
+FreeCalypso host tools is written for the clean CP2102 way, and is *not* muddied
+with the muck that would be necessary to get the high GSM baud rates with an
+unpatched ftdi_sio driver.  Therefore, if you would like to use one of the high
+GSM baud rates with FreeCalypso with an FTDI adapter, you will need to dirty
+your Linux host system with a hacky kernel patch.  The patch provided in
+linux-2.6.37.6-ftdi_sio.c.patch (made against Linux 2.6.37.6, which is what I
+use - came with Slackware 13.37 - adapt as necessary for your kernel version)
+makes the ftdi_sio driver behave like a GSM-programmed CP2102: termios B230400
+turns into 203125 baud, B460800 turns into 406250 and B921600 turns into 812500.
+
+This patch won't break other software (*cough* osmocom-bb *cough*) that does
+use the "standard" ftdi_sio way of requesting high GSM baud rates, i.e., both
+ways of selecting these baud rates should still work, but if you have other
+(non-GSM) serial devices on the same system which need 230400, 460800 or 921600
+baud, those will break.
+
+Using adapters built into phones
+================================
+
+The Calypso chip has no native USB capabilities, thus if a Calypso phone
+presents a USB charging+data port to the user, it must have a USB to serial
+converter built in.  The only phone we currently know of that does this is
+Pirelli DP-L10, and its built-in USB-serial adapter chip is CP2102.  It has
+already been programmed with the correct GSM baud rates on Foxconn's original
+production line, thus one can always use 812500 baud with FreeCalypso tools on
+this phone and it will Just Work.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/linux-2.6.37.6-ftdi_sio.c.patch	Fri Nov 06 21:46:05 2015 +0000
@@ -0,0 +1,29 @@
+--- ftdi_sio.c.orig	2011-03-27 11:01:41.000000000 -0800
++++ ftdi_sio.c	2015-10-30 13:18:40.879000032 -0800
+@@ -949,7 +949,7 @@
+ 	static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
+ 	__u32 divisor;
+ 	/* divisor shifted 3 bits to the left */
+-	int divisor3 = base / 2 / baud;
++	int divisor3 = (base / 2 + baud / 2) / baud;
+ 	divisor = divisor3 >> 3;
+ 	divisor |= (__u32)divfrac[divisor3 & 0x7] << 14;
+ 	/* Deal with special cases for highest baud rates. */
+@@ -1087,6 +1087,17 @@
+ 	baud = tty_get_baud_rate(tty);
+ 	dbg("%s - tty_get_baud_rate reports speed %d", __func__, baud);
+ 
++	/*
++	 * FreeCalypso hack: translate non-std high
++	 * baud rates for GSM like CP2102 does.
++	 */
++	if (baud == 230400)
++		baud = 203125;
++	else if (baud == 460800)
++		baud = 406250;
++	else if (baud == 921600)
++		baud = 812500;
++
+ 	/* 2. Observe async-compatible custom_divisor hack, update baudrate
+ 	   if needed */
+