Raspberry Pi Serial Port

This refers to the RS-232 traditional asynchronous serial port. Both i2c and SPI are serial in nature, but they are discussed elsewhere.

The available built-in serial port

This device is enabled in stock Raspbian, and used for a console, as an alternative to the DVI video output. It has a device file at /dev/ttyAMA0, (major 204, minor 64). Owner is root group tty, and both have it set rw (chmod 660), so users of this should be declared part of the tty group in /etc/group.

On the Raspberry Pi 3, the serial device is /dev/ttyS0 major 4, minor 64. as the /dev/ttyAMA0 has been rerouted to the Bluetooth subsystem.

The name ttyAMA0 comes from the nature of the hardware; this is an embedded ARM AMBA PL011 port, according to /etc/securetty, so that explains the AMA part of the name.

On boot, the command-line settings in /boot/cmdline.txt indicates that this is used as a console and for kernel debug output, as per entries:

console=ttyAMA0,115200
kgdboc=ttyAMA0,115200

As console is also set to tty1 here further out, which is the first in the series of ttys created using the USB keyboard/DVI screen connected. These are the familiar tty1 thru tty6, available via control-F1 thru control-F6. If these are in place that is, used as well or instead?

Once the system is started, a login-shell is run on /dev/ttyAMA0 as per an entry in /etc/inittab:

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

or an entry in the systemd subsystem. To free the port from this, we can use

systemctl stop serial-getty@ttyAMA0.service
systemctl disable serial-getty@ttyAMA0.service 

which will turn the getty off. To get it back on do enable then start on the same entity. Apparently, selecting no login-shell in the recent raspi-config tool will also disable the serial port altogether so that will not work.

Like the other signals on the Raspberry Pi GPIO connectors, this is 3.3V logic, so it needs the low-voltage 3232 level shifter to convert to the bipolar RS232 levels. Transmit is on P1 pin 8, (GPIO14) Receive is on P1 pin 10. (GPIO15)

In order to use the serial port for some other device such as an Arduino or a GPS receiver, the startup info and the shell have to be turned off, by commenting out or erasing the above entries (referring to ttyAMA0) in /etc/inittab and /boot/cmdline.txt. Similarly, if we want to run a glass-tty, we can set the speed down from 115200 to 19200 or so, as that was the old maximum capability of these.

Either way, there is something in the bootloader that emits a message at 115200 Baud right at startup, so there is a possibilty that a connected device will become a bit confused on startup. The way to deal with this would be to use one of the GPIO lines to reset the device, or gate the serial line so it isn't enabled until later, for example, when /etc/rc.local is run.

GPS and GPSD use

This is a short list to remember what is needed to change when wanting to use /dev/ttyAMA0 for a GPS receiver, emitting data at 9600 Baud. This refers not just to the serial port but to other modules and packages that have to be installed.

apt-get install gpsd gpsd-clients

edit out entries referring to /dev/ttyAMA0 from /boot/cmdline.txt

edit out getty /dev/ttyAMA0 from /etc/inittab

add stty -F /dev/ttyAMA0 9600 in /etc/rc.local

add gpsd -n -G /dev/ttyAMA0 in /etc/rc.local

In order to develop our own ntp clients using libgps (which is a lot easier than trying to talk to gpsd or ntpd directly!) we also need:

apt-get install libgps-dev

1PPS

It is also possible to use the 1PPS signal if the GPS receiver gives us one. This is an accurate pulse that has a rising edge occurring once per second, with precision on the order of microseconds or better.

This pulse is to be fed into one of the GPIO lines, and whichever GPIO line is used is referenced in /boot/config.txt. I use GPIO18 for this signal, so the line to be added at the end in this file is:

dtoverlay=pps-gpio,gpiopin=18

If another GPIO line were to be used the number after the gpiopin keyword should be set accordingly.

The kernel-module is enabled by adding this line in /etc/modules:

pps-gpio

The rest of details of use of this module from ntpd is now configured in /etc/ntp.conf

I added the following lines there:

# coarse time ref-clock
server 127.127.28.0 minpoll 4 maxpoll 4 prefer
fudge 127.127.28.0 flag1 1 time1 +0.289 refid GPS

# Kernel-mod PPS ref-clock
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 refid KPPS
fudge 127.127.22.0 flag3 1

An overview of what these special-purpose IP-addresses mean is at https://www.eecis.udel.edu/~mills/ntp/html/refclock.html and also see links from http://www.ntp.org.

Notable, on the driver 22 the flag2 determines the active edge. flag2 0 being the default of the rising edge, and flag2 1 means use the falling edge. Since the GPS unit emits its PPS timing signal with the rising edge as the reference, we set this flag2 to 0 (or leave it out as that is the default).

Another great write-up is here: http://ava.upuaut.net/?p=726.

On restart, ntpq -pn shows these local ip-addresses along with the other servers listed in the /etc/ntp.conf file:

pi@timeserver ~ $ ntpq -pn
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*127.127.28.0    .GPS.            0 l    9   16  377    0.000   33.567   6.678
o127.127.22.0    .KPPS.           0 l    7   16  377    0.000   -0.003   0.005
+51.174.102.22   85.89.3.25       2 u   34   64  377   10.887   -0.567   0.076
+139.112.1.20    139.112.153.51   2 u   64   64  377    3.809    0.920   0.065
+80.89.32.121    192.36.134.17    2 u   45   64  377   17.160   -0.486   0.046
+91.229.143.104  192.36.134.17    2 u   49   64  377    2.204    0.058   0.531
pi@timeserver ~ $ hostname -I
10.0.1.179
pi@timeserver ~ $

In order to use this as the reference clock for other machines in the network, add it as another of the servers in /etc/ntp.conf, identifying it with its IP-address or hostname; something along the lines of:

server 10.0.1.179 iburst

Running ntpq -pn there then shows:

pi@timeclient ~ $ ntpq -pn
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*10.0.1.179      .KPPS.           1 u  532 1024  377    0.689    0.183   0.078
-81.167.79.43    129.70.132.37    3 u  392 1024  373    8.440    2.382   1.135
+51.174.102.22   85.89.3.25       2 u  419 1024  377   11.345   -0.426   0.146
+92.221.137.157  85.89.3.25       2 u  361 1024  377   11.188   -0.428   0.063
-31.185.27.200   129.242.4.241    2 u  834 1024  377    3.161    0.204   0.145
pi@timeclient ~ $

USB serial ports

These are usually FTDI or PL2303 devices.

These appear when the device is plugged in, and generates devices as neede, usually in the /dev/ttyUSBn series. Seems to be a little random as to which ones appear at which times. If we want to run shells on them, we'll add a getty entry in /etc/inittab, as for example:

T1:23:respawn:/sbin/getty -L ttyUSB0 19200 vt100