How to setup Atmel-ICE to program an ATmega328 on PlatformIO with VSCode on Windows 10

I am trying to use my atmel ICE with platformIO and VS Code instead of Atmel Studio, as this software is a pain when I want to use Arduino.h with libraries.

*I posted this question on stackoverflow earlier but nobody seems to be familiar with PlatformIO enough to answer, so I decided to ask the same question on PIO community directly!

However I cannot upload with my programmer. I tried with a 32 pin ATmega328.

I first used PIO’s documentation on how to use Atmel-ICE with it on this page: debug-tools/atmel-ice

If you would like to use this tool for firmware uploading, please change upload 

protocol:
[env:myenv]
platform = ...
board = ...
debug_tool = atmel-ice
upload_protocol = atmel-ice

So this is what I wrote in my file:

[env:ATmega328P]
platform = atmelavr
board = ATmega328P
framework = arduino
upload_protocol = atmel-ice

And I get this message as I run the upload command on PIO:

DATA:    [          ]   0.4% (used 9 bytes from 2048 bytes)
PROGRAM: [          ]   1.4% (used 444 bytes from 32256 bytes)
Configuring upload protocol...
AVAILABLE: atmel-ice
CURRENT: upload_protocol = atmel-ice
Looking for upload port...
Error: Please specify `upload_port` for environment or use global `--upload-port` option.
For some development platforms it can be a USB flash drive (i.e. /media/<user>/<device name>)
*** [upload] Explicit exit, status 1

At that point I am not sure what to try. I tried a couple things described below but I am not sure I am going on the right track. The atmel ICE programmer, compared to an Arduino for example, doesn’t have a USB PORT number associated with it, so I don’t know how I am supposed to specify my upload_port argument in my .ini file.

There are some options described on the platformIO documentation Redirecting... but I am completely lost. I feel like the message I get : For some development platforms it can be a USB flash drive (i.e. /media//) can be a good clue. Any Idea what should I change in my .ini file to make my atmel ICE work? thanks!

Other things I tried: I read on a post (I’m sorry I cannot find the link anymore) that adding

upload_port = usb

can solve the issue. When adding this line to my platformio.ini, I get a different error message:

avrdude: Can't find programmer id "atmel-ice"

Valid programmers are:
  2232HIO          = FT2232H based generic programmer
  4232h            = FT4232H based generic programmer
  arduino          = Arduino

And the list goes on…

I searched and found this post, which has the same error message!: Atmega 328 - Internal 8MHZ oscillator - Atmel ICE upload troubles

The solution here was to add

upload_flags = -e 

But it didn’t change anything for me.

He also mentioned he made changes to the 328p8m.json file, which would be ATmega328P.json in my case. I don’t even know where to find it. Would that be relevant?

1 Like

The topic you referenced uses upload_protocol = atmelice_isp, what is the result of that?

@jcsb1994 @maxgerhardt is the guy to talk to, but this is what I have:

“platformio.ini”:

[env:My_328p8m]
platform = atmelavr
board = My_328p8m
framework = arduino
upload_protocol = atmelice_isp
upload_flags = -e

He also mentioned he made changes to the 328p8m.json file, which would be ATmega328P.json in my case. I don’t even know where to find it. Would that be relevant?

BOARD FILES:
PlatformIO Board Files:
C:\emacs.platformio\platforms\atmelavr\boards

My Board Files:
C:\Users\David.platformio\boards

Firmware binary file location for for board:
[PROJECT_DIRECTORY].pio\build\My_328p8m\firmware.hex

Hope this helps, brother!

1 Like

Ok, when I change the upload protocol, I get a new error message!

my .ini file:

[env:ATmega328P]
platform = atmelavr
board = ATmega328P
framework = arduino
upload_protocol = atmelice_isp
upload_port = usb
upload_flag = -e

And the error message:

DATA:    [          ]   0.4% (used 9 bytes from 2048 bytes)
PROGRAM: [          ]   1.4% (used 444 bytes from 32256 bytes)
Configuring upload protocol...
AVAILABLE: atmelice_isp
CURRENT: upload_protocol = atmelice_isp
Looking for upload port...
Use manually specified: usb
Uploading .pio\build\ATmega328P\firmware.hex

avrdude: jtag3_open_common(): Did not find any device matching VID 0x03eb and PID list: 0x2141

avrdude done.  Thank you.

*** [upload] Error 1

So I can’t find anything linked to PIO when searching this error online, it just seems it is linked to not finding atmel ICE on avrfreaks: https://www.avrfreaks.net/forum/atmel-ice-avrdude-cannot-find-device

I am pretty confused.

Do you have the Windows device manager open and can show the ICE device? The “hardware ID” section in the “Details” tab show you the vendor and product ID.

grafik

1 Like

Untitled

This is what I get. Should I use the ID to specify the upload port in some way? Im not sure how to proceed.

Well the device is there but probably can’t be opened because it seems to try libusb drivers, but you’ve installed the Atmel Studio delivered drivers for it (1-8-3/ 1-8-2 Amtel ICE Programer · Issue #6267 · arduino/Arduino · GitHub).

Can you use https://zadig.akeo.ie/ to load libusb or WinUSB drivers for it and retry?

1 Like

I also started with Atmel Studio drivers and had to switch over to libusb drivers when I first bought the Atmel Ice.

I had to install the libusb drivers a couple years ago while working with a different visual studios plugin, and back then it gave me a hard time. I don’t know if it has gotten easier since then. I don’t remember every detail, but libusb wasn’t a “verified” windows driver (or something to that effect), so I had to jump through some hoops to install in on my Windows 10 machine.

@jcsb1994 please let me know how it works out for you.

@oceansource I did not try it yet, is it a destructive procedure? Of course I’d rather have it work with PIO than Atmel Studio but if I install the wrong driver with @maxgerhardt 's website app am I going to be able to try multiple times? And is there a way to go back to the Atmel driver? I’d rather ask since an ICE is $$.

Installing the generic libusb driver should be absolutely harmless to the device, and you can always switch back the drivers in the Windows device manager to the Atmel provided ones, given you know the path to the original drivers. This is also shown in the device manager

grafik

Only thread which references a problem was solved by manually selecting the right driver in the device manager again (https://www.avrfreaks.net/comment/2435586#comment-2435586).

I’ve never seen a device which breaks by loading it with generic libusb drivers. As I said, just make sure you know where the original drivers are to switch back.

1 Like

Untitled

This is the driver I installed on my atmel ICE. now in the device manager it shows up as a libusb-win32 device. There was another driver I could’ve installed with a similar name, something like libusbk, I dont know if this one would have been better.

It doesn’t seem to change a lot of things when I press upload on platformIO. With this .ini file:

[env:ATmega328P]
platform = atmelavr
board = ATmega328P
framework = arduino
upload_protocol = atmelice_isp
upload_flag = -e 

I get:

DATA:    [          ]   0.4% (used 9 bytes from 2048 bytes)
PROGRAM: [          ]   1.4% (used 444 bytes from 32256 bytes)
Configuring upload protocol...
AVAILABLE: atmelice_isp
CURRENT: upload_protocol = atmelice_isp
Looking for upload port...
Error: Please specify `upload_port` for environment or use global `--upload-port` option.
For some development platforms it can be a USB flash drive (i.e. /media/<user>/<device name>)
*** [upload] Explicit exit, status 1

So it complains about a missing upload_port argument`. If I add:

upload_port = usb

I get:

DATA:    [          ]   0.4% (used 9 bytes from 2048 bytes)
PROGRAM: [          ]   1.4% (used 444 bytes from 32256 bytes)
Configuring upload protocol...
AVAILABLE: atmelice_isp
CURRENT: upload_protocol = atmelice_isp
Looking for upload port...
Use manually specified: usb
Uploading .pio\build\ATmega328P\firmware.hex
avrdude: usbdev_send(): wrote -22 out of 7 bytes, err = 
avrdude: jtag3_send(): failed to send command to serial port
avrdude: failed to sync with the JTAGICE3 in ISP mode

avrdude done.  Thank you.

Did I install the right driver? should I create a custom board? (I am kinda worried it looks a little complicated to do). Is it just a matter of typing the right .ini file? thanks again guys…

Well reading Unable to program AVR chips via Atmel ICE with IDE 1.6.7 · Issue #4368 · arduino/Arduino · GitHub and https://www.avrfreaks.net/comment/2255281#comment-2255281 you probably installed the libusb to only one of the devices?

Yes that is what I did haha…
But now I have both installed (I checked all available devices and there are only 2 Atmel ICE devices with the same address on zadig) and nothing changed. I get the same error reports.

Can you do a verbose upload (pio run -t upload -v) with

  1. Atmel-ICE unplugged
  2. Atmel-ICE plugged in

and post the output, starting at thte avrdude -v invocation part?

With the ICE unplugged:

avrdude -v -p atmega328p -C C:\Users\Jean-Christophe\.platformio\packages\tool-avrdude\avrdude.conf -c atmelice_isp -b 115200 -D -P "usb" -U flash:w:.pio\build\ATmega328P\firmware.hex:i

avrdude: Version 6.3, compiled on Sep 12 2016 at 17:24:16
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\Jean-Christophe\.platformio\packages\tool-avrdude\avrdude.conf"

         Using Port                    : usb
         Using Programmer              : atmelice_isp
         Overriding Baud Rate          : 115200
avrdude: jtag3_open_common(): Did not find any device matching VID 0x03eb and PID list: 0x2141

avrdude done.  Thank you.

*** [upload] Error 1
====================================================================== [FAILED] Took 7.03 seconds ======================================================================
The terminal process terminated with exit code: 1

With the ICE plugged:

avrdude -v -p atmega328p -C C:\Users\Jean-Christophe\.platformio\packages\tool-avrdude\avrdude.conf -c atmelice_isp -b 115200 -D -P "usb" -U flash:w:.pio\build\ATmega328P\firmware.hex:i

avrdude: Version 6.3, compiled on Sep 12 2016 at 17:24:16
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\Jean-Christophe\.platformio\packages\tool-avrdude\avrdude.conf"

         Using Port                    : usb
         Using Programmer              : atmelice_isp
         Overriding Baud Rate          : 115200
avrdude: usbdev_open(): Found Atmel-ICE CMSIS-DAP, serno: J42700010786
avrdude: Found CMSIS-DAP compliant device, using EDBG protocol
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : JTAG3_ISP
         Description     : Atmel-ICE (ARM/AVR) in ISP mode
         Vtarget         : 5.1 V
         SCK period      : 8.00 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: hfuse reads as D1
avrdude: safemode: efuse reads as FF
avrdude: reading input file ".pio\build\ATmega328P\firmware.hex"
avrdude: writing flash (444 bytes):

Writing | ################################################## | 100% 0.13s

avrdude: 444 bytes of flash written
avrdude: verifying flash memory against .pio\build\ATmega328P\firmware.hex:
avrdude: load data flash data from input file .pio\build\ATmega328P\firmware.hex:
avrdude: input file .pio\build\ATmega328P\firmware.hex contains 444 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.14s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0002
         0x14 != 0x34
avrdude: verification error; content mismatch

avrdude: safemode: hfuse reads as D1
avrdude: safemode: efuse reads as FF
avrdude: safemode: Fuses OK (E:FF, H:D1, L:F6)

avrdude done.  Thank you.

*** [upload] Error 1
====================================================================== [FAILED] Took 1.62 seconds ======================================================================
The terminal process terminated with exit code: 1

*note that if I do not specify upload_port = usb in the .ini, all of this does not appear and it asks for serial port to be defined.

Funny that we’re getting a lot further now.

Looks like the same error as in the referenced thread, missing a upload_flags = -e in the platformio.ini to perform a full erase beforehand. Is that already in there?

Yep that looks like an annoying bug, but that workaround is good for now

1 Like

YESS!!
we worked it out! I managed to blink a led!! Such a relief Thank you so much @maxgerhardt .

I did have upload_flag = -e without the s… I tried removing it last time as I was getting desperate.

I will post a final post on this thread explaining in details what we need to do from scratch to make the ICE work on PIO. Thanks again @maxgerhardt and @oceansource.

meanwhile, here is a video of the dead bugged blinking LED on my atmega328 board haha https://photos.app.goo.gl/sFL1jTm2ihziYVmS6

1 Like

I am a little late coming to the party… but I have had to grapple with the same issue recently… and this is what works for me…

  1. Use a custom upload protocol.
    This is what my platformio.ini file looks like.
;PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

; 'pio run -t fuses' for programming the avr fuses
; 'pio run -t program' for programming the firmware binary
; avrdude -p m328p -c atmelice_isp -U efuse:w:0xFF:m -U hfuse:w:0xD6:m -U lfuse:w:0xE2:m

[env:moteino]
platform = atmelavr
board = moteino8mhz
board_fuses.lfuse = 0xE2
board_fuses.hfuse = 0xD6
board_fuses.efuse = 0xFF
board_build.f_cpu = 8000000UL
framework = arduino
upload_protocol = custom
lib_deps = 1419
            38
            92
            126
            28
            1775
            439
upload_flags = 
    -pm328p
    -catmelice_isp
    -e
upload_command = avrdude $UPLOAD_FLAGS  -U flash:w:$SOURCE:i -C ~/.platformio/packages/tool-avrdude/avrdude.conf
extra_scripts = 
   post:scripts/post_upload_fuses.py
  1. Use the command “pio run -t program” instead of “pio run -t upload” to actually upload the firmware.

  2. There is an optional post_upload script in case one wishes to flash the fuses as well.
    This is the content of the post_upload_fuses.py

Import(“env”, “projenv”)
import subprocess

import os

# access to global construction environment

print(env)

# Dump construction environment (for debug purpose)

print(env.Dump())

def after_upload(source, target, env):
print(“Post upload actions!”)
#command to flash avr fuses to the controller
print(“Burning the AVR fuses”)
# os.system(‘avrdude -p m328p -c atmelice_isp -U efuse:w:0xFF:m -U hfuse:w:0xD6:m -U lfuse:w:0xE2:m’)
subprocess.call(‘avrdude -p m328p -C ~/.platformio/packages/tool-avrdude/avrdude.conf -c atmelice_isp -U efuse:w:0xFF:m -U hfuse:w:0xD6:m -U lfuse:w:0xE2:m’, shell=True)

env.AddPostAction(“program”,after_upload)

Of course, this a very hacky solution hard linking all the directory and file paths. I m sure more knowledgeable folks can do it right with relative paths or using environment variables.

I hope this helps… either now or someone who has the same issue in future… :slight_smile:

The solutions are all explained on my blog (hopefully clearly enough) Setting up Atmel-ICE with PlatformIO using ATmega328p – Cyan Sensors

Thanks to your help max and Ocean! I mentioned you on my blog post

3 Likes

Hi guys, I followed the above instruction but with this platformio.ini file:

[env:leonardo]
platform = atmelavr
board = leonardo
framework = arduino
board_build.f_cpu = 8000000L
lib_deps =
jandelgado/JLed@^4.11.0
arduino-libraries/ArduinoRS485@^1.0.2
septillion-git/FadeLed@^1.6.0
upload_protocol = atmelice_isp
upload_port = usb
upload_flag = -e

I get the following output:

Configuring upload protocol...
AVAILABLE: atmelice_isp
CURRENT: upload_protocol = atmelice_isp
Looking for upload port...
Using manually specified: usb
Forcing reset using 1200bps open/close on port usb
Waiting for the new upload port...
Error: Couldn't find a board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload.

I have a working Atmel ICE programmer:

$ lsusb | grep Atmel
Bus 001 Device 012: ID 03eb:2141 Atmel Corp. ICE debugger

Ubuntu 22.04. Any idea?