Firmware AVR manually
- Tutorial
Attention Image - xkcd
Imagine you are on a desert island. And it is vital for you to program the microcontroller. Why, you ask? Well, let's say to fix an emergency beacon, without which the chances of salvation fall sharply.
Rejoicing that you have not forgotten the assembler course, you somehow wrote the program with a stick in the sand. Among the things that survived, by some miracle, a printout of the documentation for the controller turned out to be nice (it’s good that you still haven’t had time to start it!), And the program managed to be translated into machine codes. The most nonsense left - to flash it into the controller. But within a radius of 500 kilometers there is not a single programmer, not to mention computers. You only have a power source (a battery of coconut
How to flash MK with bare hands?
Atmel will perform as a test subject. The described technique works with almost any controller in the AVR family, except that the command codes may vary slightly.
Interface
The most common and convenient interface for AVR firmware is SPI (Serial Peripheral Interface). To connect via SPI, you need only four wires, not counting the ground:- SCK - clock signal, synchronizes all data exchange operations;
- MOSI (Master Out Slave In) - data line from the master to the slave;
- MISO (Master In Slave Out) - data line, on the contrary, from the slave to the master;
- RESET - to enable firmware via SPI you need to apply a logical “0” to this pin.
Thus, we need to generate three signals and (optionally) read one. Here is the simplest diagram for this:
Fig. 1. The simplest connection scheme for SPI.
For your convenience, you can add an indication of the input signals. The scheme is complicated, but not excessively:
Fig. 2. Scheme with signal indication.
Bounce protection
Unfortunately, just using the buttons to generate SPI signals, we won’t achieve a good result. The reason for this is an unpleasant phenomenon called contact bounce . When closed, the mechanical contacts collide, bounce from each other, and instead of one pulse, several are obtained. To suppress bounce, you will have to assemble a simple circuit from a pair of logic elements:
Fig. 3. RS-trigger to suppress bounce.
This is an RS-trigger, which switches to state “1” at the moment of closing the lower contact of the switch and ignores the remaining pulses of bounce. Trigger reset back to “0” occurs when the upper contact closes, that is, when the button is released.
"Look, I ran away!" - the reader will say, - “I’m sitting on a desert island. Where will I get the triggers here? ” Well, you can get rid of bounce without electronic circuits. It is only necessary to replace the “dry” contact with a
MOSI and RESET signals do not require chatter suppression, unlike SCK: here only the signal level at the time of sampling is important, and not its edges.
How does SPI work?
Fig. 4. Timing diagram of the SPI.
SPI is a synchronous interface: all operations are synchronized by the edges of the clock signal (SCK), which is generated by the master. The maximum transfer rate is limited to 1/4 of the controller clock frequency. There are no restrictions on the minimum speed: without a clock signal, the data exchange is “frozen”, and the interface can remain in a static state for any length of time.
SPI transmission is carried out in full duplex mode, one bit per cycle in each direction. On the rising edge of the SCK signal, the slave device reads the next bit from the MOSI line, and on the falling edge it produces the next bit on the MISO line. All attention to figure 4.
Firmware protocol
All communication between the programmer and MK consists of sending 32-bit commands and receiving controller responses. A complete list of commands is in the datasheet, and here we list what operations must be performed for firmware MK:- Putting the controller in programming mode;
- (optional) Read device identifier;
- Erase
- Record in flash;
- (optional) Verification of the recorded;
Consider each step in detail.
Enabling programming mode
Programming mode is activated by feeding “0” to the RESET foot. But there are some subtleties. Atmel recommends that you first set the RESET and SCK terminals to a low level, and only then apply power to the controller. If this is not possible, after turning on the power, apply “0” to SCK, and then a positive pulse to RESET:
Fig. 5. Transfer MK to programming mode.
But that is not all. Next, you need to transfer the command to actually turn on the programming mode: 10101100 01010011 xxxxxxxx xxxxxxxx
Fig. 6. The command "Program Enable".
Bits denoted by x can be any. During the transmission of the third byte, the controller must send back the second byte ( 01010011) If this happens, then everything is fine, the command is accepted, the controller is waiting for further instructions. If the answer is different, you need to restart MK and try again.
ID Verification
Fig. 7. The team "Read Signature Byte".
Before you write anything in the memory of MK, you need to make sure that we have exactly the model that is needed. Each controller model has its own three-byte identifier (Signature). You can read it with commands of the form
00110000 000xxxxx xxxxxxbb xxxxxxxx
Instead of bb (the third byte of the command), substitute 00 for the first byte of the identifier, 01 for the second and 10 for the third. The corresponding byte of the identifier will be transmitted by the controller when sending the 4th byte of the command.
For ATtiny13, the identifier value is 00011110 10010000 00000111 ( 0x1E 90 07 ).
Controller Cleaning
Fig. 8. The team "Chip Erase".
The next step is to clear the MK memory, which is done by sending the “Chip Erase”
command 10101100 100xxxxx xxxxxxxx xxxxxxxx
This command erases the contents of Flash and EEPROM (all cells will contain FF), as well as the removal of lock bits if they are installed.
Write to flash memory
Program memory (Flash) in ATtiny13 consists of 512 two-byte words (1K bytes). The word address has a resolution of 9 bits. Flash memory is divided into pages, each page has a size of 16 words (a total of 32 pages). Flash recording is carried out in two stages.
First, you need to load data into the page buffer, for this, use the “Load Program Memory Page”
command 01000000 000xxxxx xxxxbbbb iiiiiiii to load the low byte of the word, and 01001000 000xxxxx xxxxbbbb iiiiiiii to load the high .
The 4 least significant bits of the 3rd byte of the bbbb command are the address of the word on the page, iiiiiiii is the load byte. First, the low byte of the word should always be loaded, and then the high byte of the same word.
Fig. 9. The command "Load Program Memory Page".
After the page buffer is loaded, you need to execute the “Write Program Memory Page” 01001100 0000000a bbbbxxxx xxxxxxxx command to write the page directly to the controller memory.
The least significant bit of the second byte and the most significant 4 bits of the third a: bbbb - five-bit page number for writing.
Fig. 10. The command "Write Program Memory Page".
All this looks rather confusing, but there is nothing complicated. The address of any byte of program memory consists of 10 bits: ppppp: bbbb: w , where
ppppp is the page number (used in the “Write Program Memory Page” command);
bbbb - address of the word on the page (in the “Load Program Memory Page” command);
w is a bit that identifies the high or low byte in a word (encrypted in the first byte of the “Load Program Memory Page” command).
Reading flash
Fig. 11. The command "Read Program Memory".
After writing the firmware to the MK, it would be nice to check the recorded data, since no data integrity check was performed. The only way to check is to read the entire amount of flash memory and compare with the original.
Reading program memory is easier than writing to it. Forget about paging, reading is byte-by-bit. The “Read Program Memory” command looks like this:
00100000 0000000a bbbbbbbbb xxxxxxxx - to read the low byte of the word, and 00101000 0000000a bbbbbbbb xxxxxxxx - for the high .
The least significant bit of the second byte and the entire third byte a: bbbbbbbbb is the address of the word in memory. The read byte is returned during the transmission of the 4th byte of the command.
Programming completion
Perhaps the easiest operation. To complete the programming and put the MK in the operating mode, it is enough to apply a logical level “1” to RESET. The controller will start and will work on the new program.
Practice
It is time to take this knowledge into practice. The victim of the experiment - ATtiny13 - is stuck in a breadboard, a signal driver is assembled nearby, everything is ready:Fig. 12. The experimental scheme.
We will sew a program of the form “there is nowhere easier”:
ldi R24, 0x02
out DDRB, R24
out PORTB,R24
L1: rjmp L1
All she does is give PB1 to her foot and go into an infinite loop. In machine codes, it takes only four words:
E082 BB87 BB88 CFFF
To flash it into the controller, you need to type the following commands:
1010 1100 0101 0011 0000 0000 0000 0000 // program enable
1010 1100 1000 0000 0000 0000 0000 0000 // chip erase
0100 0000 0000 0000 0000 0000 1000 0010 // load addr.0000 low byte 82
0100 1000 0000 0000 0000 0000 1110 0000 // load addr.0000 high byte E0
0100 0000 0000 0000 0000 0001 1000 0111 // load addr.0001 low byte 87
0100 1000 0000 0000 0000 0001 1011 1011 // load addr.0001 high byte BB
0100 0000 0000 0000 0000 0010 1000 1000 // load addr.0010 low byte 88
0100 1000 0000 0000 0000 0010 1011 1011 // load addr.0010 high byte BB
0100 0000 0000 0000 0000 0011 1111 1111 // load addr.0011 low byte FF
0100 1000 0000 0000 0000 0011 1100 1111 // load addr.0011 high byte CF
0100 1100 0000 0000 0000 0000 0000 0000 // write page
Start key, let's go!
Only 425 clicks, and MK comes to life. Now you will definitely be found and saved from this damned island.