Writing an OTA bootloader for the ATmega128RFA1 (as part of the Smart Response XE device)

Writing an OTA bootloader for the ATmega128RFA1 (as part of the Smart Response XE device)

It all started with the acquisition by the author in the secondary market of an interesting device - Smart Response XE (short description). It is intended for schools: each student in the class receives a device that looks like an electronic notebook or a translator of the nineties, the teacher asks a question, and the students type answers on the keyboards of the devices that come over the radio channel (802.15.4) to the receiver connected to the teacher's PC.

Support for these devices ended a few years ago, and what schools used to buy for $100-$200 each now pops up on eBay for $10 or less. "Iron" there is very suitable for geek experiments:

  • keyboard with 60 keys
  • display with a resolution of 384 Γ— 136, 2 bits per pixel - similar to BC, CGA, but 4 are not colors, but brightness gradations
  • microcontroller ATmega128RFA1 (128 kB flash, 4 kB ROM, 16 kB RAM, 802.15.4 transceiver)
  • external (in relation to the microcontroller, and not the entire device) flash memory for 1 megabit (128 kilobytes) with an SPI interface
  • compartment for 4 AAA elements.

By the name of the microcontroller, it is clear that it belongs to the AVR family, which means that making the device Arduino-compatible is a more than trivial task ...

From news on Hackaday the author found out that have already done (the same link tells what to connect where), having the opportunity to run games for Arduboy:


But the author is more interested in the opportunity not to play on the device, but to study:

  • flash memory with SPI serial interface
  • bootloaders for AVR
  • standard 802.15.4

The author started by writing Library (GPL v3), which allows you to initialize the display, display text and rectangles, and access flash memory with an SPI interface. Then he began to come up with ideas for the practical use of the device: a VT-100 compatible handheld terminal, multiplayer games. Having redone three devices, he decided to β€œteach” them how to receive sketches β€œover the air”. Which would be not only interesting, but also very convenient: it is difficult to open the case of the device every time, and under the battery cover there are only holes that allow you to connect a JTAG programmer to the board.

Writing an OTA bootloader for the ATmega128RFA1 (as part of the Smart Response XE device)

This is enough to fill the Arduino bootloader, but not the sketch - the serial port is not brought out there, you still can’t do without opening the case. Also, the lines TX0 and RX0 of the first serial port are aligned with the polling lines of the keyboard matrix, namely, those along which the function keys are polled on the sides of the display. But what to do - the author built this:

Writing an OTA bootloader for the ATmega128RFA1 (as part of the Smart Response XE device)

He brought the JTAG lines there, and now it is not necessary to open the battery compartment. And in order to be able to upload sketches, I connected both serial ports to the same connector, also adding a switch, because with the batteries installed, the device cannot be physically turned off in another way.

It took quite a long time to work with a soldering iron, a clerical knife and a glue gun. In general, it is much more convenient to upload sketches β€œby air”, we urgently need to invent something for this.

Arduino IDE uses a program to upload sketches avrdude. It communicates with the microcontroller using the protocol STK500, which allows you to transfer files in both directions. It is poorly compatible with channels where variable delays, distortion and data loss are possible. If something goes off or rustles on the serial link, you can go crazy looking for the cause. Once the author tormented himself for half a day until he realized that it was a bad cable, as well as a capricious CP2102 interface converter. Even a microcontroller with a built-in interface converter, for example, ATmega32u4, can sometimes be so "naughty". Every Arduino user has noticed that sketch upload errors are not uncommon. Sometimes the write goes fine, but the test read shows an error. This does not mean that the error was during the write - the failure was during the reading. Now imagine that when working "by air" the same thing will happen, but much more often.

After trying different ways to overcome this problem, the author came up with the following. The device has a 128-kilobyte flash memory with an SPI interface - we receive data via wires (remember that the author already has one device with a connector on the side), use this memory as a buffer, and send data to another device via a radio channel. Such greetings from Cybiko.

After writing the code for working with the radio channel, as well as the font, the loader became longer than 4 kilobytes. Therefore, the value of HFUSE had to be changed from 0xDA to 0xD8. Now the loader can be up to 8 kilobytes long, and the starting address has become 0x1E000. This is reflected in the Makefile, but should be taken into account when uploading bootloader using avrdude.

The 802.15.4 transceiver in the ATmega128RFA1 was originally designed to work using the protocol ZigBee, which is quite complex, so the author decided to just pass packets instead. This is implemented in hardware in the ATmega128RFA1, so little code is required. Also, for simplicity, the author decided to use a fixed channel, not allowing you to select it even manually. The 802.15.4 standard supports 16 channels numbered from 11 to 26. They are quite crowded, some also block WiFi channels (red are ZigBee channels, blue, green and yellow are WiFi).

Writing an OTA bootloader for the ATmega128RFA1 (as part of the Smart Response XE device)

It turned out that channels 15 and 26 are the least susceptible to interference from WiFi. The author chose the second of them. Disclaimer: the translator does not know if it is allowed to simplify ZigBee in this way. Maybe it's worth a little more programming and implement it completely?

On the first of the devices, it is necessary to implement a state machine that transmits data using the STK500 protocol. For the most part, transmitted and received messages are self-sufficient, but some are tied to those that passed through the channel earlier. The description of the dialogue is given here.

An important part of this dialog is the transmission of packets intended to be written to the flash memory of the destination device. For simple microcontrollers of the AVR family, the page size is 128 bytes, but for the ATmega128RFA1 it is 256. And for the flash memory that is connected via the SPI protocol, it is the same. The program in the first device, when uploading the sketch, does not immediately transfer it to the second one, but writes it to this memory. When the Arduino IDE checks the correctness of the entry, it is sent what was written there. Now we need to transmit the received data over the air to the second device. In this case, switching from reception to transmission and vice versa occurs quite often. The STK500 protocol is indifferent to delays, but does not tolerate data loss (strange, but it was said above that delays in data transfer also affect). And losses in wireless transmission are inevitable. The ATmega128RFA1 has a built-in hardware implementation of repeated requests in case of doubts about the correctness of the transfer, but the author decided to implement the same programmatically on his own. He developed a protocol in which much more data passes in one direction than in the other.

It's not perfect, but it works. A 256-byte page is divided into four segments, each of which is transmitted over the air as a packet. The packet holds up to 125 bytes of data plus one byte for the length and two for the CRC. So 64-byte fragments, along with page and segment numbers (from 0 to 3), are placed there. The receiving device has a variable to keep track of how many segments have been received, and when all four arrive, the sending device acknowledges that the entire page has been received. No confirmation (CRC did not match) - we send the entire page again. In this case, the speed is even greater than when transmitting over a cable. See:


But in general, it would be necessary to provide a convenient way to connect a cable to the devices for uploading sketches and through it. For example, put such an interface converter on the CP2102 inside, as in the photo, and glue it to the board so that it can withstand the force when connecting and disconnecting the Micro USB cable.

Writing an OTA bootloader for the ATmega128RFA1 (as part of the Smart Response XE device)

It also has a 3,3V regulator (and how to use it in a 6V powered device - as long as it has the same regulator, and you can add two diodes to automatically choose which one will power the device). All three LEDs must be removed from the interface converter board, otherwise they will additionally load the batteries when working from them, as well as interfere with polling the keyboard and working with flash memory with an SPI interface.

Pursuing a goal turned out to be even more interesting than achieving it (and no need for that joke about the bus). The author learned a lot about AVR bootloaders, SPI flash memory, STK500 protocol and 802.15.4 standard.

All other code in addition to the library described above βˆ’ here, and it is also under GPL v3. Author's twitter here.

Source: habr.com

Add a comment