# Debug Arduino Uno/ATmega328P with Adafruit CH552 QT Py and debugWire

## Introduction

Arduino IDE 2 comes with debugging capability for 32-bit Arm based Arduino boards. If you try to select Arduino Uno, you may see "Debugging is not supported by 'Arduino Uno'". This tutorial will show how to adding the missing pieces to debug Arduino Uno and other ATmega328P boards.

This tutorial will demonstrate:

1. How to convert a Adafruit CH552 QT Py into a debugWire debug probe/programmer combo (USBtinyISP compatible).&nbsp;
2. Setting up Arduino IDE 2 with board support package.
3. Automatically set fuses to enable debugging on ATmega328P.
4. Doing debugging.
5. Automatically set fuses back and restore Arduino bootloader.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/917/medium800/hacks_PXL_20241008_153646942.jpg?1728402550)

Warning: The debugging process will modify fuses to kick Arduino into debug mode. Such mode can only be exited with a functional debugger probe or High Voltage Parallel Programming. If your debugger probe is not fully functional to communicate with the Uno, your Uno may be bricked!

# Debug Arduino Uno/ATmega328P with Adafruit CH552 QT Py and debugWire

## Program CH552

## Upload code to CH552
First you need to make sure you have CH55xduino version 0.0.24 or higher. This version includes necessary patch for debug probe to work on 16MHz clock.

![hacks_Screenshot_2024-10-08_122256.png](https://cdn-learn.adafruit.com/assets/assets/000/132/938/medium640/hacks_Screenshot_2024-10-08_122256.png?1728405377)

Then you click "Tools"-\>"Board"-\>"CH55xDuino MCS51 plain C core (non-C++)"-\>CH552 Board.

![hacks_Screenshot_2024-10-08_122828.png](https://cdn-learn.adafruit.com/assets/assets/000/132/930/medium640/hacks_Screenshot_2024-10-08_122828.png?1728405474)

Choose "16 MHz (internal), 3.3V or 5V" in "Clock Source" and "USER CODE w/ 266B USB ram" in "USB settings".

Choose "16 MHz (internal), 3.3V or 5V" in "Clock Source" and "USER CODE w/ 266B USB ram" in "USB settings".

![hacks_Screenshot_2024-10-08_123033.png](https://cdn-learn.adafruit.com/assets/assets/000/132/935/medium640/hacks_Screenshot_2024-10-08_123033.png?1728405498)

![hacks_Screenshot_2024-10-08_123045.png](https://cdn-learn.adafruit.com/assets/assets/000/132/942/medium640/hacks_Screenshot_2024-10-08_123045.png?1728405508)

Compile and upload code. Hold middle button and connect CH552 board to computer, and flash the firmware. More info for this setup can be found in Adafruit CH552 QT Py tutorial.

### Adafruit CH552 QT Py - Manual Bootloader

[Adafruit CH552 QT Py](https://learn.adafruit.com/adafruit-ch552-qt-py)
[Manual Bootloader](https://learn.adafruit.com/adafruit-ch552-qt-py/bootloader-mode)
Windows User only:

AVRDUDE tool shipped with Arduino IDE is relatively old and requires a&nbsp;LibUSB driver. Using&nbsp;[Zadig](https://learn.adafruit.com/admin/guides/4100/editor/zadig.akeo.ie)&nbsp;to install the libusb-win32 driver.

![hacks_installDriverInWindows.png](https://cdn-learn.adafruit.com/assets/assets/000/132/945/medium640/hacks_installDriverInWindows.png?1728405911)

Let's test if the Adafruit CH552 QT Py is working properly.

Switch board to "Arduino Uno".

Select "Programmer" as "USBTinyISP".

Click "Burn Bootloader".

You should see some failure like "initialization failed, rc=-1" because there isn't an Arduino connected yet. But this message indicates the CH552 respond to computer correctly.

However, if you see "Error: Could not find USBtiny device (0x1781/0xc9f)". That means the CH552 is not working properly, you need to check the compile settings, driver, or check if it is visible in device manager in your computer's OS.

![hacks_Screenshot_2024-10-08_124629.png](https://cdn-learn.adafruit.com/assets/assets/000/132/946/medium640/hacks_Screenshot_2024-10-08_124629.png?1728406272)

![hacks_Screenshot_2024-10-08_124643.png](https://cdn-learn.adafruit.com/assets/assets/000/132/947/medium640/hacks_Screenshot_2024-10-08_124643.png?1728406315)

![hacks_Screenshot_2024-10-08_124700.png](https://cdn-learn.adafruit.com/assets/assets/000/132/948/medium640/hacks_Screenshot_2024-10-08_124700.png?1728406392)

![hacks_Screenshot_2024-10-08_124739.png](https://cdn-learn.adafruit.com/assets/assets/000/132/949/medium640/hacks_Screenshot_2024-10-08_124739.png?1728406977)

![hacks_Screenshot_2024-10-08_125006.png](https://cdn-learn.adafruit.com/assets/assets/000/132/950/medium640/hacks_Screenshot_2024-10-08_125006.png?1728406990)

Then you would connect an Arduino Uno's ISP port to CH552. The 5V and GND should be connected. The Reset of Arduino should be connected to A0(P1.1) of CH552. And SPI lines (SCK, MISO, MOSI) should be connected to corresponding pins on CH552.

![](https://cdn-learn.adafruit.com/assets/assets/000/132/926/medium800/hacks_debug_bb.png?1728404244)

After connecting your Arduino. If every wire is connected properly. The power LED on Arduino should be on. And if you burn bootloader once more, you should see "avrdude done. &nbsp;Thank you." that shows a successful burn.

![hacks_Screenshot_2024-10-08_140823.png](https://cdn-learn.adafruit.com/assets/assets/000/132/953/medium640/hacks_Screenshot_2024-10-08_140823.png?1728410922)

Congratulations! Now you have a fully functional debugWire debug probe/programmer combo (USBtinyISP compatible).

You may also use the probe/programmer combo for other AVR chip just like a USBtinyISP.

# Debug Arduino Uno/ATmega328P with Adafruit CH552 QT Py and debugWire

## Connect Arduino

Cut the trace between "RESET-EN" to disconnect it.

![hacks_PXL_20241008_154506798.jpg](https://cdn-learn.adafruit.com/assets/assets/000/133/066/medium640/hacks_PXL_20241008_154506798.jpg?1728567870)

![hacks_Screenshot_2024-10-10_094659.png](https://cdn-learn.adafruit.com/assets/assets/000/133/067/medium640/hacks_Screenshot_2024-10-10_094659.png?1728568113)

Info: On Arduino Uno, the USB-Serial adaptor controls the RESET pin of ATMega328P through the capacitor. This capacitor will absorb high frequency debug signal and we disconnect it.

Doing so will disable the auto-bootloader entry feature on Arduino. But we won't using it during debug so we can solder the pads back after debugging.

Connect the Arduino the same way as we test the Arduino.

The 5V and GND should be connected. The Reset of Arduino should be connected to A0(P1.1) of CH552. And SPI lines (SCK, MISO, MOSI) should be connected to corresponding pins on CH552.

![hacks_debug_bb.png](https://cdn-learn.adafruit.com/assets/assets/000/133/068/medium640/hacks_debug_bb.png?1728568428)

In Arduino IDE2,&nbsp;Add board "Arduino 8-bit with Debug" by,

Clicking "File"-\>"Preferences"

Click the button on the right side of&nbsp;_Additional boards manager URLs_

In the text box, add a new row of the link in the next text box. A long URL seem breaks the layout of this page.&nbsp;

In board manager, search "debug" and install the board "Arduino 8-bit with Debug"

&nbsp;

![hacks_Screenshot_2024-10-10_100110.png](https://cdn-learn.adafruit.com/assets/assets/000/133/069/medium640/hacks_Screenshot_2024-10-10_100110.png?1728575427)

![hacks_Screenshot_2024-10-10_100120.png](https://cdn-learn.adafruit.com/assets/assets/000/133/089/medium640/hacks_Screenshot_2024-10-10_100120.png?1728575641)

![hacks_Screenshot_2024-10-10_100140.png](https://cdn-learn.adafruit.com/assets/assets/000/133/090/medium640/hacks_Screenshot_2024-10-10_100140.png?1728575654)

![hacks_Screenshot_2024-10-10_100211.png](https://cdn-learn.adafruit.com/assets/assets/000/133/091/medium640/hacks_Screenshot_2024-10-10_100211.png?1728575669)

URL here:

[https://raw.githubusercontent.com/DeqingSun/unoDebugTestPackage/main/package\_uno\_debug\_index.json](https://raw.githubusercontent.com/DeqingSun/unoDebugTestPackage/main/package_uno_debug_index.json)

Now open the code you'd like to debug. Select board "Arduino Uno with dwire-debug". The port does not matter as we are not using it.

"Verify" the code to compile it.

Click the left of the line number to add a breakpoint. Then click "Debug".

After a few seconds, the code will pause at the breakpoint. You may add othe breakpoint, view data value, modify data value, stepping, etc. Just like a regular debugger.&nbsp;

You may stop by click the stop button.

![hacks_Screenshot_2024-10-10_100810.png](https://cdn-learn.adafruit.com/assets/assets/000/133/073/medium640/hacks_Screenshot_2024-10-10_100810.png?1728569350)

![hacks_Screenshot_2024-10-10_100932.png](https://cdn-learn.adafruit.com/assets/assets/000/133/074/medium640/hacks_Screenshot_2024-10-10_100932.png?1728569413)

![hacks_Screenshot_2024-10-10_101251.png](https://cdn-learn.adafruit.com/assets/assets/000/133/075/medium640/hacks_Screenshot_2024-10-10_101251.png?1728569613)

![hacks_Screenshot_2024-10-10_101409.png](https://cdn-learn.adafruit.com/assets/assets/000/133/076/medium640/hacks_Screenshot_2024-10-10_101409.png?1728569667)

When you are done with debugging. You can flash the bootloader back and solder the "RESET-EN" back.

"Power cycle" the Arduino by unplug it and plug it back to your computer.

Try to burn the bootloader twice. The 1st try will fail as expect.

The 2nd try will be successful.

![hacks_Screenshot_2024-10-10_103147.png](https://cdn-learn.adafruit.com/assets/assets/000/133/077/medium640/hacks_Screenshot_2024-10-10_103147.png?1728570731)

![hacks_Screenshot_2024-10-10_103321.png](https://cdn-learn.adafruit.com/assets/assets/000/133/078/medium640/hacks_Screenshot_2024-10-10_103321.png?1728570836)

![hacks_Screenshot_2024-10-10_103329.png](https://cdn-learn.adafruit.com/assets/assets/000/133/079/medium640/hacks_Screenshot_2024-10-10_103329.png?1728570847)

Info: The entering and leaving of debug mode requires changing the fuse bit. ATmega328P only allow you to change it one in each power cycle. That is the reason why you would replug the Arduino before leaving the debug mode.

The In-System Programming (ISP) will not work in debug mode. And the CH552 has special code in such a failure and try to send command to take the ATmega328P out of debug mode. That's how the 2nd burn will be successful.

Solder a dab of solder across the RESET-EN to restore the auto-upload feature.

![hacks_PXL_20241008_154149498.jpg](https://cdn-learn.adafruit.com/assets/assets/000/133/081/medium640/hacks_PXL_20241008_154149498.jpg?1728571738)

# Debug Arduino Uno/ATmega328P with Adafruit CH552 QT Py and debugWire

## How does everything works

## How does Arduino IDE do the debug?

On the computer, we are running the IDE, debugger and debugger server. The IDE will interact with user, while debugger translates between c codes and machine codes. And the debugger server acts as a bridge between the debugger and debug hardware. On the hardware side, the debug probe will act as a bridge and connects the debug target and the debug server.

In Arduino IDE case, it uses a plug-in "Cortex Debug" from Marus to do debugging. This plug-in is supposed to debug a Arm Cortex microcontroller with GDB and OPENOCD. 8-bit AVR chip does not have OPENOCD and we have a modified version of dwire-debug to mimic an OPENOCD to make the full chain work.

When you do some debugging operation in Arduino IDE, for example adding a break point, Arduino IDE will tell GDB to add a breakpoint at a line in C code, GDB will figure out which memory address the breakpoint should be, dwire will convert it to debugwire commands, and the CH552 will send the signals to a ATmegs328P to add such a breakpoint.

![](https://cdn-learn.adafruit.com/assets/assets/000/133/084/medium800/hacks_Screenshot_2024-10-10_110019.png?1728572479)

## Why official Arduino Uno board does not support debug while "Arduino Uno with dwire-debug" support debug?

The "Arduino Uno with dwire-debug" is using the same compiler and board support files to the official Arduino Uno. However a Arduino Uno board does not come with debug probe, and the official Arduino Uno board package does not come with a debug server.&nbsp;

The CH552 board act as a debug probe, and the "Arduino Uno with dwire-debug" package includes a debug server, that why we can do debugging with these components.

## How debug works in signal level?

The debug-wire is a single wire half-duplex serial protocol. It runs on 128 division of the CPU speed. So for a 16Mhz Arduino, the communication will be 125K baud rate.

Before communication, the probe can pull the signal down for some time to send a break signal. After the break signal the ATmega328P will respond a 0x55 signal for probe to measure the baudrate.

After that, the probe can send command in serial and the ATmega328P will respond. For example, the probe send "0xF3" to read the chip signature, and the ATmega328P respond "0x95, 0x0F" that indicate itself is a ATmega328P.

There is no official release of the protocol and all works are based on reverse engineering. More info can be found on [https://www.ruemohr.org/docs/debugwire.html](https://www.ruemohr.org/docs/debugwire.html)

![](https://cdn-learn.adafruit.com/assets/assets/000/133/058/medium800/hacks_Screen_Shot_2024-10-09_at_10.04.37_PM.png?1728526652)

![](https://cdn-learn.adafruit.com/assets/assets/000/133/059/medium800/hacks_Screen_Shot_2024-10-09_at_10.05.12_PM.png?1728526662)

![](https://cdn-learn.adafruit.com/assets/assets/000/133/060/medium800/hacks_Screen_Shot_2024-10-09_at_10.05.55_PM.png?1728526672)


## Featured Products

### Adafruit CH552 QT Py - 8051 Dev Board with STEMMA QT

[Adafruit CH552 QT Py - 8051 Dev Board with STEMMA QT](https://www.adafruit.com/product/5960)
What a cutie pie! Or is it... a QT Py? This diminutive dev board comes with a throwback processor - an 8-bit 8051! This tiny core is a big change from something like the the [ESP32-S3 QT Py with two 240MHz 32-bit cores](https://www.adafruit.com/product/5700), but there's lots of...

In Stock
[Buy Now](https://www.adafruit.com/product/5960)
[Related Guides to the Product](https://learn.adafruit.com/products/5960/guides)
### Arduino Uno R3

[Arduino Uno R3](https://www.adafruit.com/product/1545)
 **Arduino Uno** is a microcontroller board based on the ATmega328P ([datasheet](https://cdn-shop.adafruit.com/product-files/4806/4806_Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf)). It has 14 digital input/output pins (of which 6 can be used as PWM...

In Stock
[Buy Now](https://www.adafruit.com/product/1545)
[Related Guides to the Product](https://learn.adafruit.com/products/1545/guides)

## Related Guides

- [Adafruit CH552 QT Py](https://learn.adafruit.com/adafruit-ch552-qt-py.md)
- [Quickstart IoT - Raspberry Pi Pico RP2040 with WiFi ](https://learn.adafruit.com/quickstart-rp2040-pico-with-wifi-and-circuitpython.md)
- [Adafruit IO Basics: Analog Output](https://learn.adafruit.com/adafruit-io-basics-analog-output.md)
- [Cosplay Hacks](https://learn.adafruit.com/cosplay-hacks.md)
- [Alternative languages for programming the SAMD51 boards](https://learn.adafruit.com/alternative-languages-for-programming-samd-boards.md)
- [Adafruit IO Basics: Digital Input](https://learn.adafruit.com/adafruit-io-basics-digital-input.md)
- [Working with Multiple Same Address I2C Devices](https://learn.adafruit.com/working-with-multiple-i2c-devices.md)
- [Colorful Creations with the New JLCPCB PCB Service](https://learn.adafruit.com/colorful-creations-with-the-new-jlcpcb-pcb-service.md)
- [Plotting Offline Data - JSONL to CSV files, filters and graphs](https://learn.adafruit.com/plotting-offline-data-jsonl-to-csv-files-filters-and-graphs.md)
- [Quadcopter Spray Can Mod](https://learn.adafruit.com/quadcopter-spray-can-mod.md)
- [Arduino Lesson 1. Blink](https://learn.adafruit.com/adafruit-arduino-lesson-1-blink.md)
- [Arduino GPS Clock](https://learn.adafruit.com/arduino-clock.md)
- [Build a Bluetooth App using Swift 5](https://learn.adafruit.com/build-a-bluetooth-app-using-swift-5.md)
- [Phyx LANA TNY CH32V203](https://learn.adafruit.com/phyx-lana-tny-ch32v203.md)
- [Arduino Lesson 16. Stepper Motors](https://learn.adafruit.com/adafruit-arduino-lesson-16-stepper-motors.md)
- [A REST API for Arduino & the CC3000 WiFi Chip](https://learn.adafruit.com/a-rest-api-for-arduino-and-the-cc3000-wifi-chip.md)
