This post is motivated by the lack of information about using debugWire with an Arduino (or similar) on the web. There are quite a few brief comments on the forums and people asking how to do it but nothing really good, with the possible exception of a post by Steve Cogswell which refers to an old version of Arduino and an old version of Atmel Studio.
This really notes for myself for next time, when I’m bound to have forgotten the recipe, but I hope someone else will find it useful. The previous post describes how to get started with using the Atmel Studio simulator, which is a good introduction to the activities required during on-chip debugging (OCD) without needing to fiddle quite so much and without wondering whether the hardware is playing nicely.
What Can You Do with debugWire?
Inspect memory, single-step through code, set break-points (at which execution will stop), inspect registers and input/output port values etc. i.e. as for the simulator, but for the real hardware.
This assumes you have:
- an Arduino Uno
- Atmel Studio 6 (Windows only but you could try using it from inside VirtualBox if you are a linux or Mac user – I’ve had a good experience of VirtualBox on Ubuntu, although I’ve not tried Atmel Studio )
- an AVR Dragon (a fairly cheap USB programmer/on-chip-debugger) and a 6-way cable to connect it.
I also recommend you get the ATMega328 data sheet.
Preparing the Hardware
The ATMega328 data sheet says:
• Capacitors connected to the RESET pin must be disconnected when using debugWire.
• All external reset sources must be disconnected.
If you check the Arduino Schematic, you will see that there IS a 100nF capacitor connected to RESET. This is used to cause a reset to be triggered when communication is initiated via the USB. This is normally useful since a reset is needed to prompt the bootloader on the Arduino to receive compiled code in the upload process.
In the older Arduinos you had to remove the capacitor (as per Steve Cogswell’s post) but on the Uno there is a bit of circuit board track specially prepared for cutting and re-soldering later if need be. If you leave it cut then it will be necessary to manually press the reset button just as the Arduino IDE (or avrdude) tries to start an upload.
Preparing the Software
This is basically just a case of compiling the code for the Arduino in Atmel Studio as I’ve previously described. It is NOT necessary to upload the compiled code using avrdude because Atmel Studio will do this for us via debugWire.
Preparing the Hardware
Connect the Dragon ISP header to the Arduino ISP header. Note that pin1 connects to pin1 on the other device, i.e. MISO connects to MISO. Both Dragon and Ardiuno are separately powered through their USB connectors and the Dragon senses the Arduino’s power supply voltage through the 6-way connector.
You can also “Read” the device signature to confirm that the physical device matches the one chosen in Atmel Studio. This will happen automatically later on anyway and Atmel Studio will block you if it isn’t right.
Warning… and Being Prepared
As described in Steve Cogswell’s post, it is possible to make a non-permanent mess of the ATMega328. It may be necessary to use the “HV” programming on the AVR Dragon if the ATMega gets stuck in debugWire mode and it may be necessary to re-install the boot-loader. These are not difficult if you have an AVR Dragon (or presumably other programmers too).
It can be useful if you need to recover from mishap, and is generally a good plan, I think, to get the fuse settings BEFORE messing about with debugWire and before fiddling with them. All you need to convert a factory fresh ATMega328 into something usable on an Arduino board is to set the fuses correctly and to program the boot loader.
The debugWire Cycle
This is the sequence of operations I have found works reliably. Try this with “Blink” (if you’ve carried on from the simulation example, remember to replace the delay() lines). NB: step 7 is important to get your chip back into its normal state.
- Program the DWEN fuse: make sure the box is ticked then click “Program”.
- Cycle the power on the Arduino by temporarily disconnecting the USB connector. At this point, you can probably no longer use the ISP interface.
- Set debugWire as the interface (see screenshot below)
- Click “Start Debugging and Break” or hit Alt+F5 or set a break-point then “Start Debugging” (F5). Note: this uploads the program too.
- Set break-points, single-step etc. Use the “IO View” to manually change the value of output pins on the Arduino, yes, the real ones!
- Stop debugging (Ctrl+Shift+F5), change the code and return to step 4.
- Menu “Debug|Disable debugWIRE and close”. This menu item is only accessible when debugging so you may need to use F5 again. The DWEN flag will now be reset and you will be able to use the ISP interface again.
Now compare the fuses and lock-bits to the previously saved settings. They should be identical. debugWIRE should also have preserved the bootloader so it should be possible to go back to the Arduino IDE; you only need to remember to press the Arduino reset button just as the IDE announces it is uploading in order that the bootloader executes.