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

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?

Add

board_upload.wait_for_upload_port = no
board_upload.use_1200bps_touch = no

to the platformio.ini. Does it still try to wait for serial port?

With those two lines I get this output:

Configuring upload protocol...
AVAILABLE: atmelice_isp
CURRENT: upload_protocol = atmelice_isp
Looking for upload port...
Using manually specified: usb
Uploading .pio/build/leonardo/firmware.hex
avrdude: usbdev_open(): WARNING: failed to set configuration 1: Device or resource busy

avrdude: stk500v2_command(): command failed
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

Well now it’s at least trying to talk to the Atmel ICE, but it doesn’t get far. Per other topics like Atmel-ICE with macOS Catalina - #6 by jeanlouis.lumia it should work okay.

There is a post at Unfreeze Your Atmel-ICE – Arduino Craft Corner about a custom avrdude version. Does the last command, adapated to avrdude -c atmelice_isp -p m32u4 -v -t , show something?

I issued it in a terminal:

$ avrdude -c atmelice_isp -p m32u4 -v -t

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

         System wide configuration file is "/etc/avrdude.conf"
         User configuration file is "/home/marcotrapanese/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : usb
         Using Programmer              : atmelice_isp
avrdude: Found CMSIS-DAP compliant device, using EDBG protocol
         AVR Part                      : ATmega32U4
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PA0
         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  9000  9000 0x00 0x00
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 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         : 0.0 V
         SCK period      : 1.00 us

avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x61
avrdude: stk500v2_jtag3_recv(): error in jtagmkII_recv()
avrdude: AVR device initialized and ready to accept instructions

Reading |                                                    | 0% 0.00savrdude: jtag3_edbg_send(): Unexpected response 0x81, 0x11
avrdude: jtag3_edbg_recv(): Unexpected response 0x80
avrdude: stk500v2_jtag3_recv(): error in jtagmkII_recv()
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_send(): Unexpected response 0x81, 0x11
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x71
avrdude: stk500v2_jtag3_recv(): error in jtagmkII_recv()
Reading | #################                                  | 33% 0.84s
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_send(): Unexpected response 0x81, 0x11
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x61
avrdude: stk500v2_jtag3_recv(): error in jtagmkII_recv()
Reading | ################################################## | 100% 1.44s

avrdude: Device signature = 0x303030
avrdude: Expected signature for ATmega32U4 is 1E 95 87
         Double check chip, or use -F to override this check.
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_send(): Unexpected response 0xc0, 0x54
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x71
avrdude: stk500v2_jtag3_recv(): error in jtagmkII_recv()
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_send(): Unexpected response 0x70, 0x54
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x61
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_send(): Unexpected response 0x17, 0x00
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x71
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_signoff(): failed to read from serial port (0)

avrdude done.  Thank you.

That’s not looking too good. It did find your device this time, but talking to the microcontroller failed completely. Either there is something wrong with the wiring between the AtmelICE and the target board or Atmel ICE firmware somehow has a fault or avrdude still has a fault. Sadly I have neither a Mac nor an Atmel ICE to further investigate this. The next recommended stop would be the avrdude programmers maybe. Issues · avrdudes/avrdude · GitHub

Before you open an issue there it might be worth compiling the very-latest avrdude version yourself and seeing if that created binary has the same problem. See Building AVRDUDE for macOS · avrdudes/avrdude Wiki · GitHub. Make sure to brew remove the old avrdude version.

Atmel Studio (within VirtualBox) programs correctly my board, so both the wirings and the programmer are ok.

I was just looking for a way to program the hex file without running Windows in the virtual machine.
By the way, I’m running Ubuntu 22.04 not a MAC.

The new avrdude version 7 has major refactorings – it’s worth trying it out, maybe it solves your previous problems.

1 Like

Oh actually, the github CI already builds it for you.

avrdude-macos-x86_64

too late :slight_smile:

I’ve already built the master branch from github and… it works!
I hate when they (Ubuntu-guys) use packages without testing them…

If you have a folder with the built avrdude executable and the avrdude.conf (like in the CI build I showed above), you can add a package.json file to it with content

{
  "name": "tool-avrdude",
  "version": "1.70000.223005",
  "description": "AVRDUDE is a utility to download/upload/manipulate the ROM and EEPROM contents of AVR microcontrollers",
  "keywords": [
    "tools",
    "uploader",
    "microchip",
    "avr"
  ],
  "homepage": "http://savannah.nongnu.org/projects/avrdude",
  "license": "GPL-2.0-or-later",
  "system": [
    "darwin_x86_64",
    "darwin_arm64"
  ],
  "repository": {
    "type": "svn",
    "url": "http://svn.savannah.gnu.org/viewvc/avrdude/"
  }
}

and given that you have PlatformIO commands available in the CLI (guide) you can the execute pio package pack in that folder. This will give you a .tar.gz file. You can then get back to your PlatformIO project and make PlatformIO use this working version of avrdude by specifying the path to that package file

platform_packages =
   tool-avrdude@file://<path to .tar.gz here>

(docs) in the platformio.ini using the file:// protocol.

Does it work then within PlatformIO?

I’m going to try your last suggestion. Anyway, without any other change, it seems to work in platformio as well:


Configuring upload protocol...
AVAILABLE: atmelice_isp
CURRENT: upload_protocol = atmelice_isp
Looking for upload port...
Using manually specified: usb
Uploading .pio/build/leonardo/firmware.hex

avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading input file ".pio/build/leonardo/firmware.hex"
avrdude: writing flash (12256 bytes):

Writing | ################################################## | 100% 0.80s

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

Reading | ################################################## | 100% 0.67s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0202
         0x00 != 0x84
avrdude: verification error; content mismatch

avrdude: safemode: Fuses OK (E:FB, H:D8, L:FF)

avrdude done.  Thank you.

Now I’m trying to understand if the mismatch error is real or not.

Is it always the same byte position if you do it multiple times?

Usually the -e flag is supposed to get rid of that error by performing an erase beforehand. Does it work if you manually avrdude -e ... it on the commandline?

1 Like

Yep. On the command line the erase flag does the trick.
But platformio seems to ignore the upload_flag = -e line in the ini file.

1 Like

Oh that’s because it must be upload_flags = -e as documented. Did someone post it here without the s?

1 Like

Ah ok! Yes, there are at least a couple of messages here above without the trailing s

1 Like

You know someway to performance a configuration to use ATMELICE in Microchip Studio and Platformio? The both at the same time… because I use Atmel Studio to debug in some cases since platformio is not possible.

I know that Atmel Studio require:

  • ATMEL-ICE CMSIS-DAP (Interface 0) as driver HID
  • ATMEL-ICE DATA GATEWAY (Interface 1) as driver WinUSB

Thanks :slightly_smiling_face:
RAR.