Skip to content

Commit a399c36

Browse files
committed
renamed and clarified serial chapter, cleaned up UART chapter a bit
The description of serial ports and serial communication was pretty confusing: now it's much cleaner. The new chapter name `Serial Port` should help, as it unambiguously describes the thing we will actually be working with. closes #78
1 parent 386a174 commit a399c36

File tree

9 files changed

+134
-184
lines changed

9 files changed

+134
-184
lines changed

mdbook/src/09-registers/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This chapter is a technical deep-dive. You can safely [skip it] for now and come back to it later if
44
you like. That said, there's a lot of good stuff in here, so I'd recommend you dive in.
55

6-
[skip it]: ../10-serial-communication/index.html
6+
[skip it]: ../10-serial-port/index.html
77

88
-----
99

mdbook/src/10-serial-communication/README.md

Lines changed: 0 additions & 65 deletions
This file was deleted.

mdbook/src/10-serial-communication/nix-tooling.md

Lines changed: 0 additions & 95 deletions
This file was deleted.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Serial Port
2+
3+
<a href="https://en.wikipedia.org/wiki/File:Serial_port.jpg">
4+
<p align="center">
5+
<img height="240" title="Standard serial port connector DE-9" src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Serial_port.jpg/800px-Serial_port.jpg" />
6+
</p>
7+
</a>
8+
9+
<p align="center">
10+
<em>This is what we'll be using. I hope your computer has one!</em>
11+
</p>
12+
13+
Nah, don't worry. This connector, the DE-9 (often referred to as DB-9), went out of fashion on PCs quite some time ago; it got replaced by the Universal Serial Bus (USB). We won't be dealing with the DE-9 connector itself but with the communication protocol that this cable is/was usually used for.
14+
15+
So what's this [serial port]? It's a communication channel where two devices exchange data *serially*, as in one bit at a time, using two data lines (plus a common ground). Communication is asynchronous, in the sense that neither of the shared lines carries a clock signal. Instead, both parties must agree on approximately how fast data will be sent along the wire *before* the communication occurs. A peripheral called a Universal Asynchronous Receiver/Transmitter (UART) sends bits at the specified rate on its output wire, and watches for the start of bits on its input wire. This protocol channel thus allows *duplex* communication: data can be sent from A to B on one wire, while data is also being sent from B to A on the other wire.
16+
17+
(Old school-serial ports also include a number of other wires for "out-of-band signalling", to tell the hardware when the connection is active, when the other end is ready to receive, etc. These wires are rarely used today, and are often not implemented in serial port hardware.)
18+
19+
We'll be using a serial port to exchange data between the microcontroller and your computer. Now you might be asking yourself why exactly we aren't using RTT for this like we did before. RTT is a protocol that is meant to be used solely for debugging. You will most definitely not be able to find a device that actually uses RTT to communicate with some other device in production. However, serial communication is used quite often. For example some GPS receivers send the positioning information they receive via serial communication. In addition RTT, like many debugging protocols, is slow even compared to serial transfer rates.
20+
21+
The next practical question you probably want to ask is: How fast can we send data through this protocol?
22+
23+
The serial-port communications protocol works with frames, each carrying a byte of data. Each frame has one *start* bit, 5 to 9 bits of payload (data: modern applications very rarely send a 9-bit byte, and 7 or fewer bits in a frame will be left-padded to an 8-bit byte with zeros) and 1 to 2 *stop bits*.
24+
25+
The speed of the protocol is known as *baud rate* and it's quoted in bits per second (bps). (If you're thinking that this sounds wrong — it is. "Baud" is supposed to be *symbols* per second; a symbol should correspond to a frame; even if a data bit is regarded as the "symbol" they aren't sent at this rate because of the rest of the protocol. It's a convention, and doesn't have to make sense.) Historically common baud rates are: 9600, 19200, 38400, 57600 and 115200, but it is not uncommon in our modern world to send data at 921,600 baud.
26+
27+
To actually answer the question: With a common configuration of 1 start bit, 8 bits of data, 1 stop bit and a bit rate of 921.6K bps we can send and receive 92.16K bytes per second — fast enough to transmit single-channel uncompressed CD audio. At the bit rate of 115,200 bps that we'll be using, we can send and receive 11.52K bytes per second. This is fine for most purposes.
28+
29+
Today's computers don't usually have a serial port, and even if they do the voltage they use (+5V on a modern serial port, ±12V on an ancient RS-232 port) is outside the range that the MB2 hardware will accept and may result in damaging it. *You can't directly connect your computer to the microcontroller.* You *can* buy very inexpensive (typically under US$5) USB←→serial converters that will support the +3.3V inputs of most modern microcontroller boards. We will be talking to the MB2 serial port through its built-in USB port. However, if you want to connect directly to a hardware serial port, on the MB2 or some other board, a serial converter is the way to go.
30+
31+
A separate USB channel on the MB2's USB port can be used to talk to the MB2's built-in USB←→serial converter. This means that the converter sits between the MB2 USB port and the microcontroller serial port, exposing a serial interface to the microcontroller and a virtual USB serial interface to your computer. The computer presents a virtual serial interface via the USB CDC-ACM ("Communications Device Class - Abstract Control Model", ugh) device class. The MB2 microcontroller will see your computer as a device connected to its hardware serial port; your computer will see the MB2 serial port as a virtual serial device.
32+
33+
Now, let's get familiar with the USB serial port interface that your OS offers. Pick a route:
34+
35+
- [Linux/UNIX](nix-tooling.md)
36+
- [Windows](windows-tooling.md)
37+
38+
For MacOS check out the Linux documentation, although your experience may differ somewhat.
39+
40+
[serial port]: https://en.wikipedia.org/wiki/Serial_port
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Linux USB←→serial tooling
2+
3+
The MB2's USB emulated serial device shows up in Linux when you connect the MB2 to a Linux USB
4+
port.
5+
6+
## Connecting the MB2 board
7+
8+
If you connect the MB2 board to your computer you should see a new TTY device appear in
9+
`/dev`.
10+
11+
``` console
12+
$ sudo dmesg -T | tail | grep -i tty
13+
[63712.446286] cdc_acm 1-1.7:1.1: ttyACM0: USB ACM device
14+
```
15+
16+
This is the USB←→serial device. On Linux, it's named `tty` (for "TeleTYpe", believe it or not). It
17+
should show up as `ttyACM0`, or maybe `ttyUSB0`. If other "ACM" devices are plugged in, the number
18+
will be higher. (On Mac OS `ls /dev/cu.usbmodem*` will show the serial device.)
19+
20+
But what exactly is `ttyACM0`? It's a file of course! Everything is a file in Unix:
21+
22+
```
23+
$ ls -l /dev/ttyACM0
24+
crw-rw----+ 1 root plugdev 166, 0 Jan 21 11:56 /dev/ttyACM0
25+
```
26+
27+
Note that you will need to be either running as `root` (not advised) or a member of the group that
28+
appears in the `ls` output (usually `plugdev` or `dialout`) to read and write this device. You can
29+
then send out data by simply writing to this file:
30+
31+
``` console
32+
$ echo 'Hello, world!' > /dev/ttyACM0
33+
```
34+
35+
You should see the orange LED on the MB2, right next to the USB port, blink for a moment,
36+
whenever you enter this command.
37+
38+
## minicom
39+
40+
We'll use the program `minicom` to interact with the serial device using the keyboard. We will use
41+
the default settings of modern `minicom`: 115200 bps, 8 data bits, one stop bit, no parity bits, no
42+
flow control. (115200 bps happens to be a rate that will work with the MB2.)
43+
44+
``` console
45+
$ minicom -D /dev/ttyACM0
46+
```
47+
48+
This tells `minicom` to open the serial device at `/dev/ttyACM0`. A text-based user interface
49+
(TUI) will pop out.
50+
51+
<p align="center">
52+
<img title="minicom" src="../assets/minicom.png" />
53+
</p>
54+
55+
You can now send data using the keyboard! Go ahead and type something. Note that
56+
the text UI will *not* echo back what you type. If you pay attention to the yellow LED
57+
on top of the MB2 though, you will notice that it blinks whenever you type something.
58+
59+
## `minicom` commands
60+
61+
`minicom` exposes commands via keyboard shortcuts. On Linux, the shortcuts start with `Ctrl+A`. (On
62+
Mac, the shortcuts start with the `Meta` key.) Some useful commands below:
63+
64+
- `Ctrl+A` + `Z`. Minicom Command Summary
65+
- `Ctrl+A` + `C`. Clear the screen
66+
- `Ctrl+A` + `X`. Exit and reset
67+
- `Ctrl+A` + `Q`. Quit with no reset
68+
69+
> **NOTE** Mac users: In the above commands, replace `Ctrl+A` with `Meta`.

mdbook/src/10-serial-communication/windows-tooling.md renamed to mdbook/src/10-serial-port/windows-tooling.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Windows tooling
22

3-
Start by unplugging your micro:bit.
3+
Start by unplugging your MB2.
44

5-
Before plugging the micro:bit back in, run the following command on the terminal:
5+
Before plugging the MB2 back in, run the following command on the terminal:
66

77
``` console
88
$ mode
@@ -12,9 +12,9 @@ It will print a list of devices that are connected to your computer. The ones th
1212
in their names are serial devices. This is the kind of device we'll be working with. Take note of
1313
all the `COM` ports' `mode` outputs *before* plugging the serial module.
1414

15-
Now, plug in the micro:bit and run the `mode` command again. If you see a new
15+
Now, plug in the MB2 and run the `mode` command again. If you see a new
1616
`COM` port appear on the list, then that's the COM port assigned to the
17-
serial functionality on the micro:bit.
17+
serial functionality on the MB2.
1818

1919
Now launch `putty`. A GUI will pop out.
2020

@@ -41,6 +41,6 @@ Finally, click the Open button. A console will show up now:
4141
<img title="PuTTY console" src="../assets/putty-console.png" width="500" />
4242
</p>
4343

44-
If you type on this console, the yellow LED on top of the micro:bit will blink. Each keystroke
44+
If you type on this console, the yellow LED on top of the MB2 will blink. Each keystroke
4545
should make the LED blink once. Note that the console won't echo back what you type so the screen
4646
will remain blank.

mdbook/src/11-uart/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# UART
22

3-
Our microcontroller (like most) has a peripheral called a UART (for "Universal Asynchronous
4-
Receiver/Transmitter). This peripheral can be configured to work with several serial communication
5-
protocols. The peripheral we will be working with is named UARTE (for "UART with Easy DMA", a topic
6-
outside the scope of this chapter).
3+
Our microcontroller (like most) has UART ("Universal Asynchronous Receiver/Transmitter)
4+
peripherals. There are two kinds of UART peripheral on the MB2: the older `UART` and the newer
5+
`UARTE` ("UART with Easy DMA"). We will use a `UARTE` peripheral to talk to our hardware serial
6+
port.
77

88
Throughout this chapter, we'll use serial communication to exchange information between the
99
microcontroller and your computer.

mdbook/src/11-uart/send-a-single-byte.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,26 @@ uarte::Uarte::new(
2929
This function takes ownership of the UARTE peripheral representation in Rust (`board.UARTE0`) and
3030
the TX/RX pins on the board (`board.uart.into()`) so nobody else can mess with either the UARTE
3131
peripheral or our pins while we are using them. After that we pass two configuration options to the
32-
constructor: the baud rate (that one should be familiar) as well as an option called "parity". Parity
33-
is a way to allow serial communication lines to check whether the data they received was corrupted
34-
during transmission. We don't want to use that here so we simply exclude it. Then we wrap it up in
35-
the `UartePort` type so we can use it.
32+
constructor: the baud rate (that one should be familiar) as well as an option called
33+
"parity". Parity is a way to allow serial communication lines to check whether the data they
34+
received was corrupted during transmission. We don't want to use that here so we simply exclude it.
35+
Then we wrap it up in the `UartePort` type so we can use it.
3636

37-
After the initialization, we send our `X` via the newly created uart instance. These serial
38-
functions are "blocking": they wait for the data to be sent before returning. This is not always
39-
what is wanted: the microcontroller can do a lot of work while waiting for the byte to go out on the
40-
wire. However, in our case it is convenient and we didn't have other work to do anyway.
37+
After the initialization, we send our `X` (as ASCII byte value 88) via the newly created uart
38+
instance. These serial functions are "blocking": they wait for the data to be sent before
39+
returning. This is not always what is wanted: the microcontroller can do a lot of work while
40+
waiting for the byte to go out on the wire. However, in our case it is convenient and we didn't
41+
have other work to do anyway.
4142

4243
Last but not least, we `flush()` the serial port. This is because the UARTE may decide to buffer
4344
output until it has received a certain number of bytes to send. Calling `flush()` forces it to
4445
write the bytes it currently has right now instead of waiting for more.
4546

4647
## Testing it
4748

48-
Before flashing this you should make sure to start your minicom/PuTTY as the data we receive via our
49-
serial communication is not backed up or anything: we have to view it live. Once your serial monitor
50-
is up you can flash the program just like in chapter 5:
49+
Before flashing this you should make sure to start your minicom/PuTTY as the data we receive via
50+
our serial communication is not backed up or anything: we have to view it live. Once your serial
51+
monitor is up you can flash the program just like in chapter 5:
5152

5253
```
5354
$ cargo embed --example send-byte

0 commit comments

Comments
 (0)