Using a CP2103 to program an ATMEGA328-PU

Hi all!

As an exercise to learn KiCad, I copied the Adafruit Boardunio design. It's a bare bones UNO, just the ATMEGA328P-PU and support components for it to function. My post on the KiCad forum detailing what I did can be found here

Ordered PCB boards and parts and built one, and it works. I was confused about chips and ended up ordering a 328-PU, instead of the 328P-PU used in an UNO. This caused a few problems because it was the wrong chip, but I eventually got it programmed by using my official Ardunio UNO as a programmer.

Because I need to learn how to work with SMD electronics, I kind of copied some of the designs I've seen out there for programmers for the 328, to make a programmer for my board. For example, the Adafruit Metro line of boards use 328P-PU and a CP2104 USB to UART chip to program the 328P-PU. The ESP32 devkit boards I use have a CP2102, I think, to handle that task. My design uses the CP2103 and can be found in my KiCad fourm post here

My problem is I'm running into errors when trying to program my home brew 328-PU. When using the Adruino IDE I get the following error messages:

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM4
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xa8
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xa8

When, in the IDE, I look at Tools -> Get Board Info I get these details:

BN: Unknown board
VID: 10C4
PID: EA60
SN: Upload any sketch to obtain it

An Adafruit Metro in the Arduino form factor returns this info:

BN: Unknown board
VID: 10C4
PID: EA60
SN: Upload any sketch to obtain it

My real UNO returns:

BN: Arduino Uno
VID: 2341
PID: 0043
SN: 95437313035351913192

Since I'm getting info from my board, I assume it's working, it's returning VID and PID info that matches Adafruit's Metro. I can program my Metro, my UNO, but not this board....

where am I going wrong?
how to get more info from avrdude?

Thanks for any help,
Randy

This chip doesn’t handle the CTS ( or another hand shaking signal I forget which) signal correctly. This is used to reset the Arduino and put it into boot mode. This is not happening.

As a temporary work around you can hold down the reset button on your clone and release it just as the display says uploading code. It is a bit hit or miss but you should get the hang of releasing it at the right point.

I see. I haven't had any luck with holding down the reset button and releasing it as you described.

I was not aware of this. Should I be looking at using the CP2102 instead?

Thanks for your help!
Randy

Can you post the bit of the circuit that shows the CP2103 with its connections to the USB as well as to the Arduino and reset circuit.

Here's the CP2103 schematic:

The J2 connector plugs into the JP7 connector of my clone:

One thing to note here is that the 3.3v output from the CP2103 board is not connected to the arduino clone, I only use a 5 pin header on the CP2103 board.

There could very well be an error on the CP2103 board. There also could be an error in my building of the CP2103 board, as it is my first attempt at SMD assembly. I had a solder stencil made for the board, applied solder paste, placed components, and re-flow with a clothes iron. I have examined the solder connections and they appear fine, but I don't have a good magnification device. I have a cheap helper hands thing with a magnifying glass on it. I also don't have meter probes for this kind of work, so I can't check for continuity.

95% sure the clone board is up to par. I can use my UNO to program it, and it just works.

Thanks for any help,
Randy

Yes no surprise.
Sorry when I said the CTS I meant the DTR but when I said that didn't work that was on the CP2102, not the CP2103.
Let's assume for a moment that the CP2103 handles the DTR correctly.

The mistake you have made is to connect the DTR of the CP2103 directly to the reset pin. In fact it needs to be connected to the reset through a series capacitor, 0.1uF seems normal. This converts the logic level into a pulse and it is this pulse that resets the Arduino. With it connected directly your CP2103 is holding the Arduino permanently in reset.

The other thing that worries me is that the CP2103 is being powered by 3V3, which means all the signals out are at 3V3 logic levels which technically below the minimum high a 5V Arduino needs, but often you get away with that. However one thing you won't get away with is that the 5V TX signal from the Arduino is too high for the 3V3 maximum input of the CP2103's RX input. This needs to be cut down with a potential divider, before any damage is done. ( It might be too late for your chip ).

As you have a PCB of the circuit you must use the well known practice used in industrial development of altering the circuit using a sharp scalpel to cut tracks and thin wire to make any contacts.
You should be able to cut the track from the DTR output and bridge it with a hand soldered surface mount capacitor. A smiler technique should be use for the potential divider.

I'll be the first to admit, I'm not 100% sure I know what I am doing, so I should not doubt you.

The CP2103 DTR line is pin 6 of the J2 header. When connected to the clone, it is pin 6 of JP7 header, the RTS# net in it's schematic. It's connected to the 328 RESET with capacitor C6. So I think I have it connected right.

This is what I understand too, you can get away with 3V3.

Looking at the CP2103 data sheet, Table 1 suggests it will handle 5.8V on any I/O pin. Or am I not understanding the data sheet?

I do have some logic level converters and could breadboard one in between the CP2103 board and the clone, just to be sure. I think the CP2103 is ok, because it returns Board Info in the arduino IDE. There is a software tool for adjusting it's settings that I have been thinking of using it to see if the chip responds. I'll try these things and report my results.

Thanks,
Randy

The data sheet says about that value

Which is not the same thing as handling it. It might not work under those conditions, I fact it might not work with anything above the supply voltage.

You will see Table 3 doesn’t have a maximum input voltage, that doesn’t mean there is none, it means at the power rail.

I would also check that the DTR line is high when the converter is connected to a USB line and selected in a serial monitor.

The DTR line is low when the board isn't connected to the clone and a terminal window in the IDE is open. The DTR line is high @3.53~4ish volts when connected to the clone.

I have a few of these logic level converters and wired one up on a breadboard between the clone and the CP2103 boards. To my surprise, I'm getting serial data from the clone.

The clone is running a blink program with serial prints of the current state of the LED, and I'm seeing those prints in the serial monitor.

Attempting to upload code to the clone gives me basically the same error messages as before.

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM4
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x6c
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x65
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x64
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x20
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x2d
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x20
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x6f
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x66
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x66
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x0d

avrdude done.  Thank you.

An error occurred while uploading the sketch

But at least now, I'm getting some response from the CP2103.

I hope my info helps and a lot of thanks to you for helping me on this project.

Randy

That is very odd. According to the schematics all the DTR line is connected to is a capacitor, so your clone can't be pulling it up. Are you sure that it is not 3V3 you are seeing on the DTR line?

With it connected and the clone running a blink can you remove just the DTR line from the clone and see if the high voltage drops?

On the CP2103, by itself (not connected to anything), the DTR line is 3.54v without a serial monitor. With a serial monitor open, the DTR line is 0.

Yes, it is the 3v3. I checked the 3v3 output of the CP2103 and it is 3.54 volts. Meter bounces from 3.53 to 3.54 volts. I guess I should have checked that closer before posting.

I did not check this, I assume you asked because of my previous error.

Can you explain to me how this all works? When I search for info, I keep getting results on how to program an arduino with another arduino, but nothing on the inner workings of this process.

I'm assuming it is something like this: DTR line drops low, capacitor discharges, DTR line goes high and the capacitor charging slows that down enough that the 328 resets. Bootloader on the 328 executes after reset and looks for serial data to store away in program memory space. Is that how it works?

Thanks for pointing out my misunderstanding of the data sheet! So I have the level shifter in there and I'm getting data from the 328 into a serial monitor. Now what do I need to look at to get a program to upload to the 328?

Cheers,
Randy

DTR drops low, the other side of the cap drops low as well, causing a reset. The cap charges through the RESET pullup resistance(s), taking the AVR out of reset, and...

That's about how it works thereafter. DTR going high again is not required. (but it does have to go high again before another LOW transition can cause another reset.)
(The "automatic" operation happened because DTR goes "true" (low) when a com port is opened, and high when the port is closed.)

Details of the (Optiboot) bootloader operation are described here: HowOptibootWorks · Optiboot/optiboot Wiki · GitHub

Nearly correct.
"DTR line goes high and the capacitor charging slows"
When one end of a capacitor suddenly changes voltage, the other end of the capacitor instantly follows that change.
So a capacitor with both ends at ground has no charge in it. If one end goes to 3V3, then so does the other end, because the charge on the capacitor (in this case no charge) has to be maintained. This causes a hig voltage on the reset pin which causes the reset.

But now there is a voltage across the capacitor and so it starts to charge up, which causes previously grounded end, which has jumped to a high voltage to start to drop, thus releasing the reset.

So how & when does the DTR line change values? DTR - Data Terminal Ready - when it's high does that mean there is data ready to be sent? Then, does it drop to low when the data is sent? Does it stay low while the data is sent, or does it just drop to low for an instant and return to high while the data transmission is happening?

In my research on my problems, I thought I saw a DTR signal from an oscilloscope, it dropped to low quickly then slowly returned to high. The drop to low was a vertical line, the return to high was a sloped/curved line, happening over time. It's times like this I wish I had a scope, but I need one so rarely that I can't justify the cost of one...

Thanks,
Randy

When it has its USB circuit activated from a host computer.

No it stays high all the time it is connected to the USB and the host computer has it enabled. You can get problems with some computer languages on the host computer only activating it when it has something to send. This causes repeated resets on an Arduino.

Good news, I got it working!

There were 2 problems with this. First, I didn't understand the datasheet for the CP2103 corectly. Thanks to @Grumpy_Mike I corrected that problem. I thought I could use the CP2103 with a 5v system.

Once I added in a level shifter between the CP2103 and my clone UNO, I started to receive data from the UNO clone, but still couldn't program it with the CP2103.

Then I realized I was using an ATMEGA328-PU, the UNO uses a ATMEGA328P-PU. Notice the extra P in there? I didn't when I ordered it. This caused me problems when I first tried to program the chip using another arduino as a programmer, see here. So I removed the 328P-PU from my UNO and inserted it in my clone, and now the programmer worked.

When using another UNO as a programmer trying to program my chip, I would get an error message that a device signature wasn't correct. The 328P-PU has a different signature than the 328-PU. Using the CP2103 to program the 328-PU, I didn't get the signature incorrect error message, so I didn't think about the incorrect signature.

Anyway, this is solved. I have some 328P-PU ordered and will be using those in the future and throwing the 328-PU away.

Thanks for the help!
Randy

PS - one last thing - my CP2103 programmer has TX and RX LEDs connected to GPIO pins 0 and 1 of the CP2103. Those LEDs weren't working. Following this guide I had to download and use Simplicity Studio to change the configuration of the CP2103 to enable those LEDs.

FYI; MiniCore supports ATmega328 (without P!) and you can be use it as an Arduino.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.