diff --git a/mdbook/src/09-registers/README.md b/mdbook/src/09-registers/README.md index ca98e708..1af7f00f 100644 --- a/mdbook/src/09-registers/README.md +++ b/mdbook/src/09-registers/README.md @@ -3,7 +3,7 @@ This chapter is a technical deep-dive. You can safely [skip it] for now and come back to it later if you like. That said, there's a lot of good stuff in here, so I'd recommend you dive in. -[skip it]: ../10-serial-communication/index.html +[skip it]: ../10-serial-port/index.html ----- diff --git a/mdbook/src/10-serial-communication/README.md b/mdbook/src/10-serial-communication/README.md deleted file mode 100644 index d171887b..00000000 --- a/mdbook/src/10-serial-communication/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Serial communication - - -

- -

-
- -

-This is what we'll be using. I hope your computer has one! -

- -Nah, don't worry. This connector, the DE-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. - -So what's this [*serial communication*][ASC]? It's an *asynchronous* communication protocol where -two devices exchange data *serially*, as in one bit at a time, using two data lines (plus a common -ground). The protocol is asynchronous in the sense that neither of the shared lines carries a clock -signal. Instead, both parties must agree on how fast data will be sent along the wire *before* the -communication occurs. This protocol allows *duplex* communication as data can be sent from A to B -and from B to A simultaneously. - -We'll be using this protocol 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. - -The next practical question you probably want to ask is: How fast can we send data through this -protocol? - -This protocol works with frames. Each frame has one *start* bit, 5 to 9 bits of payload (data) and 1 -to 2 *stop bits*. The speed of the protocol is known as *baud rate* and it's quoted in bits per -second (bps). Common baud rates are: 9600, 19200, 38400, 57600 and 115200 bps. - -To actually answer the question: With a common configuration of 1 start bit, 8 bits of data, 1 stop -bit and a baud rate of 115200 bps one can, in theory, send 11,520 frames per second. Since each one -frame carries a byte of data, that results in a data rate of 11.52 KB/s. In practice, the data rate -will probably be lower because of processing times on the slower side of the communication (the -microcontroller). - -Today's computers don't usually support the serial communication protocol, and even if they do the -voltage they use, ±5..12V, may be higher than the micro:bit will accept and may result in damaging -it. You can't directly connect your computer to the microcontroller. You *can* buy very inexpensive -USB←→serial converters that will support the 0..3V most modern microcontroller boards need. While a -serial converter is not necessary for the MB2, as shown below, it can be handy for inexpensive -boards that have few communications options other than serial.) - -The debug probe on the micro:bit itself can act as a USB←→serial converter. This means that the -converter will sit between the two and expose a serial interface to the microcontroller and a USB -interface to your computer. The microcontroller will see your computer as another serial device and -your computer will see the microcontroller as a virtual serial device. - -Now, let's get familiar with the serial module and the serial communication tools that your OS -offers. Pick a route: - -- [Linux/UNIX](nix-tooling.md) -- [Windows](windows-tooling.md) - -For MacOS check out the Linux documentation, although your experience may differ somewhat. - -[ASC]: https://en.wikipedia.org/wiki/Asynchronous_serial_communication diff --git a/mdbook/src/10-serial-communication/nix-tooling.md b/mdbook/src/10-serial-communication/nix-tooling.md deleted file mode 100644 index 6c13c8e6..00000000 --- a/mdbook/src/10-serial-communication/nix-tooling.md +++ /dev/null @@ -1,95 +0,0 @@ -# Linux USB←→serial tooling - -The micro:bit's USB emulated serial device shows up in Linux when you connect the MB2 to a Linux USB -port. - -## Connecting the micro:bit board - -If you connect the micro:bit board to your computer you should see a new TTY device appear in -`/dev`. - -``` console -$ sudo dmesg -T | tail | grep -i tty -[63712.446286] cdc_acm 1-1.7:1.1: ttyACM0: USB ACM device -``` - -This is the USB←→serial device. On Linux, it's named `tty` (for "TeleTYpe", believe it or not). It -should show up as `ttyACM0`, or maybe `ttyUSB0`. If other "ACM" devices are plugged in, the number -will be higher. (On Mac OS `ls /dev/cu.usbmodem*` will show the serial device.) - -But what exactly is `ttyACM0`? It's a file of course! Everything is a file in Unix: - -``` -$ ls -l /dev/ttyACM0 -crw-rw----+ 1 root plugdev 166, 0 Jan 21 11:56 /dev/ttyACM0 -``` - -Note that you will need to be either running as `root` (not advised) or a member of the group -`plugdev` to read and write this device. You can then send out data by simply writing to this file: - -``` console -$ echo 'Hello, world!' > /dev/ttyACM0 -``` - -You should see the orange LED on the micro:bit, right next to the USB port, blink for a moment, -whenever you enter this command. - -## minicom - -We'll use the program `minicom` to interact with the serial device using the keyboard. - -We must configure `minicom` before we use it. There are quite a few ways to do that but we'll use a -`.minirc.dfl` file in the home directory. Create a file in `~/.minirc.dfl` with the following -contents: - -``` console -$ cat ~/.minirc.dfl -pu baudrate 115200 -pu bits 8 -pu parity N -pu stopbits 1 -pu rtscts No -pu xonxoff No -``` - -> **NOTE** Make sure this file ends in a newline! Otherwise, `minicom` will fail to read the last -> line. - -That file should be straightforward to read (except for the last two lines), but nonetheless let's -go over it line by line: - -- `pu baudrate 115200`. Sets baud rate to 115200 bps. -- `pu bits 8`. 8 bits per frame. -- `pu parity N`. No "parity check bit", which would be used for error detection. -- `pu stopbits 1`. 1 stop bit. -- `pu rtscts No`. No hardware flow control. -- `pu xonxoff No`. No software flow control. - -Once that's in place, we can launch `minicom` on our ACM device, for example: - -``` console -$ minicom -D /dev/ttyACM0 -b 115200 -``` - -This tells `minicom` to open the serial device at `/dev/ttyACM0` and set its -baud rate to 115200. A text-based user interface (TUI) will pop out. - -

- -

- -You can now send data using the keyboard! Go ahead and type something. Note that -the text UI will *not* echo back what you type. If you pay attention to the yellow LED -on top of the micro:bit though, you will notice that it blinks whenever you type something. - -## `minicom` commands - -`minicom` exposes commands via keyboard shortcuts. On Linux, the shortcuts start with `Ctrl+A`. (On -Mac, the shortcuts start with the `Meta` key.) Some useful commands below: - -- `Ctrl+A` + `Z`. Minicom Command Summary -- `Ctrl+A` + `C`. Clear the screen -- `Ctrl+A` + `X`. Exit and reset -- `Ctrl+A` + `Q`. Quit with no reset - -> **NOTE** Mac users: In the above commands, replace `Ctrl+A` with `Meta`. diff --git a/mdbook/src/10-serial-port/README.md b/mdbook/src/10-serial-port/README.md new file mode 100644 index 00000000..651834c9 --- /dev/null +++ b/mdbook/src/10-serial-port/README.md @@ -0,0 +1,40 @@ +# Serial Port + + +

+ +

+
+ +

+This is what we'll be using. I hope your computer has one! +

+ +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. + +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. + +(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.) + +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. + +The next practical question you probably want to ask is: How fast can we send data through this protocol? + +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*. + +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. + +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. + +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. + +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. + +Now, let's get familiar with the USB serial port interface that your OS offers. Pick a route: + +- [Linux/UNIX](nix-tooling.md) +- [Windows](windows-tooling.md) + +For MacOS check out the Linux documentation, although your experience may differ somewhat. + +[serial port]: https://en.wikipedia.org/wiki/Serial_port diff --git a/mdbook/src/10-serial-port/nix-tooling.md b/mdbook/src/10-serial-port/nix-tooling.md new file mode 100644 index 00000000..b45f6488 --- /dev/null +++ b/mdbook/src/10-serial-port/nix-tooling.md @@ -0,0 +1,69 @@ +# Linux USB←→serial tooling + +The MB2's USB emulated serial device shows up in Linux when you connect the MB2 to a Linux USB +port. + +## Connecting the MB2 board + +If you connect the MB2 board to your computer you should see a new TTY device appear in +`/dev`. + +``` console +$ sudo dmesg -T | tail | grep -i tty +[63712.446286] cdc_acm 1-1.7:1.1: ttyACM0: USB ACM device +``` + +This is the USB←→serial device. On Linux, it's named `tty` (for "TeleTYpe", believe it or not). It +should show up as `ttyACM0`, or maybe `ttyUSB0`. If other "ACM" devices are plugged in, the number +will be higher. (On Mac OS `ls /dev/cu.usbmodem*` will show the serial device.) + +But what exactly is `ttyACM0`? It's a file of course! Everything is a file in Unix: + +``` +$ ls -l /dev/ttyACM0 +crw-rw----+ 1 root plugdev 166, 0 Jan 21 11:56 /dev/ttyACM0 +``` + +Note that you will need to be either running as `root` (not advised) or a member of the group that +appears in the `ls` output (usually `plugdev` or `dialout`) to read and write this device. You can +then send out data by simply writing to this file: + +``` console +$ echo 'Hello, world!' > /dev/ttyACM0 +``` + +You should see the orange LED on the MB2, right next to the USB port, blink for a moment, +whenever you enter this command. + +## minicom + +We'll use the program `minicom` to interact with the serial device using the keyboard. We will use +the default settings of modern `minicom`: 115200 bps, 8 data bits, one stop bit, no parity bits, no +flow control. (115200 bps happens to be a rate that will work with the MB2.) + +``` console +$ minicom -D /dev/ttyACM0 +``` + +This tells `minicom` to open the serial device at `/dev/ttyACM0`. A text-based user interface +(TUI) will pop out. + +

+ +

+ +You can now send data using the keyboard! Go ahead and type something. Note that +the text UI will *not* echo back what you type. If you pay attention to the yellow LED +on top of the MB2 though, you will notice that it blinks whenever you type something. + +## `minicom` commands + +`minicom` exposes commands via keyboard shortcuts. On Linux, the shortcuts start with `Ctrl+A`. (On +Mac, the shortcuts start with the `Meta` key.) Some useful commands below: + +- `Ctrl+A` + `Z`. Minicom Command Summary +- `Ctrl+A` + `C`. Clear the screen +- `Ctrl+A` + `X`. Exit and reset +- `Ctrl+A` + `Q`. Quit with no reset + +> **NOTE** Mac users: In the above commands, replace `Ctrl+A` with `Meta`. diff --git a/mdbook/src/10-serial-communication/windows-tooling.md b/mdbook/src/10-serial-port/windows-tooling.md similarity index 79% rename from mdbook/src/10-serial-communication/windows-tooling.md rename to mdbook/src/10-serial-port/windows-tooling.md index 79408a1d..195c3de1 100644 --- a/mdbook/src/10-serial-communication/windows-tooling.md +++ b/mdbook/src/10-serial-port/windows-tooling.md @@ -1,8 +1,8 @@ # Windows tooling -Start by unplugging your micro:bit. +Start by unplugging your MB2. -Before plugging the micro:bit back in, run the following command on the terminal: +Before plugging the MB2 back in, run the following command on the terminal: ``` console $ mode @@ -12,9 +12,9 @@ It will print a list of devices that are connected to your computer. The ones th in their names are serial devices. This is the kind of device we'll be working with. Take note of all the `COM` ports' `mode` outputs *before* plugging the serial module. -Now, plug in the micro:bit and run the `mode` command again. If you see a new +Now, plug in the MB2 and run the `mode` command again. If you see a new `COM` port appear on the list, then that's the COM port assigned to the -serial functionality on the micro:bit. +serial functionality on the MB2. Now launch `putty`. A GUI will pop out. @@ -41,6 +41,6 @@ Finally, click the Open button. A console will show up now:

-If you type on this console, the yellow LED on top of the micro:bit will blink. Each keystroke +If you type on this console, the yellow LED on top of the MB2 will blink. Each keystroke should make the LED blink once. Note that the console won't echo back what you type so the screen will remain blank. diff --git a/mdbook/src/11-uart/README.md b/mdbook/src/11-uart/README.md index c0f12384..6e5482ca 100644 --- a/mdbook/src/11-uart/README.md +++ b/mdbook/src/11-uart/README.md @@ -1,9 +1,9 @@ # UART -Our microcontroller (like most) has a peripheral called a UART (for "Universal Asynchronous -Receiver/Transmitter). This peripheral can be configured to work with several serial communication -protocols. The peripheral we will be working with is named UARTE (for "UART with Easy DMA", a topic -outside the scope of this chapter). +Our microcontroller (like most) has UART ("Universal Asynchronous Receiver/Transmitter) +peripherals. There are two kinds of UART peripheral on the MB2: the older `UART` and the newer +`UARTE` ("UART with Easy DMA"). We will use a `UARTE` peripheral to talk to our hardware serial +port. Throughout this chapter, we'll use serial communication to exchange information between the microcontroller and your computer. diff --git a/mdbook/src/11-uart/send-a-single-byte.md b/mdbook/src/11-uart/send-a-single-byte.md index 96ef771a..15f57fe1 100644 --- a/mdbook/src/11-uart/send-a-single-byte.md +++ b/mdbook/src/11-uart/send-a-single-byte.md @@ -29,15 +29,16 @@ uarte::Uarte::new( This function takes ownership of the UARTE peripheral representation in Rust (`board.UARTE0`) and the TX/RX pins on the board (`board.uart.into()`) so nobody else can mess with either the UARTE peripheral or our pins while we are using them. After that we pass two configuration options to the -constructor: the baud rate (that one should be familiar) as well as an option called "parity". Parity -is a way to allow serial communication lines to check whether the data they received was corrupted -during transmission. We don't want to use that here so we simply exclude it. Then we wrap it up in -the `UartePort` type so we can use it. +constructor: the baud rate (that one should be familiar) as well as an option called +"parity". Parity is a way to allow serial communication lines to check whether the data they +received was corrupted during transmission. We don't want to use that here so we simply exclude it. +Then we wrap it up in the `UartePort` type so we can use it. -After the initialization, we send our `X` via the newly created uart instance. These serial -functions are "blocking": they wait for the data to be sent before returning. This is not always -what is wanted: the microcontroller can do a lot of work while waiting for the byte to go out on the -wire. However, in our case it is convenient and we didn't have other work to do anyway. +After the initialization, we send our `X` (as ASCII byte value 88) via the newly created uart +instance. These serial functions are "blocking": they wait for the data to be sent before +returning. This is not always what is wanted: the microcontroller can do a lot of work while +waiting for the byte to go out on the wire. However, in our case it is convenient and we didn't +have other work to do anyway. Last but not least, we `flush()` the serial port. This is because the UARTE may decide to buffer output until it has received a certain number of bytes to send. Calling `flush()` forces it to @@ -45,9 +46,9 @@ write the bytes it currently has right now instead of waiting for more. ## Testing it -Before flashing this you should make sure to start your minicom/PuTTY as the data we receive via our -serial communication is not backed up or anything: we have to view it live. Once your serial monitor -is up you can flash the program just like in chapter 5: +Before flashing this you should make sure to start your minicom/PuTTY as the data we receive via +our serial communication is not backed up or anything: we have to view it live. Once your serial +monitor is up you can flash the program just like in chapter 5: ``` $ cargo embed --example send-byte diff --git a/mdbook/src/SUMMARY.md b/mdbook/src/SUMMARY.md index 06d61187..13eceaec 100644 --- a/mdbook/src/SUMMARY.md +++ b/mdbook/src/SUMMARY.md @@ -37,9 +37,9 @@ - [`0xBAAAAAAD` address](09-registers/bad-address.md) - [Spooky action at a distance](09-registers/spooky-action-at-a-distance.md) - [Type safe manipulation](09-registers/type-safe-manipulation.md) -- [Serial communication](10-serial-communication/README.md) - - [\*nix tooling](10-serial-communication/nix-tooling.md) - - [Windows tooling](10-serial-communication/windows-tooling.md) +- [Serial Port](10-serial-port/README.md) + - [\*nix tooling](10-serial-port/nix-tooling.md) + - [Windows tooling](10-serial-port/windows-tooling.md) - [UART](11-uart/README.md) - [Send a single byte](11-uart/send-a-single-byte.md) - [Send a string](11-uart/send-a-string.md)