Custom AVR XMEGA board

Hi,

I usually program in Microchip Studio aka Atmel Studio :yum:, but I would like to configure Visual Studio Code as my current IDE to flash embedded systems.

So, I would like to know how is the process to performance a good configuration of a new board if it is not available in the list of framework boards.
This is the board I woul like to flash and debug with ATMELICE: atxmega256a3u from Microchip AVR XMEGA low power microcontrollers.

First, I created a new custom board and I added to root path (.platformio/boards)
Here is the code:

{
    "build": {
      "f_cpu": "2000000L",
      "variant": "64pin-standard",
      "hwids": [
        [
          "0x1234",
          "0x0013"
        ],
        [
          "0x4567",
          "0x0013"
        ]
      ],
      "mcu": "atxmega256a3u"
    },
    "hardware": {
      "oscillator": "internal"
    },
    "platforms": ["atmelavr"],
    "name": "atxmega256a3u",
    "upload": {
      "maximum_ram_size": 16384,
      "maximum_size": 262144
    },
    "url": "https://www.microchip.com/en-us/product/ATXMEGA256A3U",
    "vendor": "Microchip"
  }

And, I don’t have idea how to continue the process, I am not an expert in platformio framework. But I would like to improve because I know it is very poweful.

Thanks and I hope you can help me :pleading_face:
RAR.

Are the (brief|) docs here of any use to you?

Cheers,
Norm.

What is your target framework? Just avr-gcc with their avr libc, or Arduino? Because for Arduino, I only see the 128 chip being supported in arduino/variants at master ¡ XMegaForArduino/arduino ¡ GitHub.

Yes, I have used it to create the new board.json file that I attached in the post message.

Thanks,
RAR.

I would like to use avr-gcc without Arduino framework.

If you don’t plan on having Arduino support (which is a whole different hole), then you don’t need a variant attibute, because that selects the Arduino variant folder in the core.

This attribute will be ignored by PlatformIO in regards to fuse selection because of this code. For now you can assume fuses are correct and PlatformIO doesn’t need to auto-generate them or burn them.

This is not used in board files at all, only in library.json files. I would have expected a frameworks array, even if it is empty, like in here.

You are missing the upload protocol, aka the -c <programmer> switch passed to avrdude. You need to tell it to use your AtmelICE in JTAG mode here probably.

See platform-atmelavr/boards/328p16m.json at develop ¡ platformio/platform-atmelavr ¡ GitHub and avrdude.conf.

You probably want this config, aka the upload section should be

    "upload": {
      "maximum_ram_size": 16384,
      "maximum_size": 262144,
      "protocol": "atmelice"
    },

With that it’s already enough to test-compile and test-upload a simple firmware. Assuming you saved the JSON file under the name you should create any new project (e.g., “Uno” + Arduino), override the project’s platformio.ini with

[env:atxmega256a3u]
platform = atmelavr
board = atxmega256a3u

rename the auto-genned src/main.cpp to src/main.c

#include <avr/io.h>
#include <util/delay.h>

int main() {
 // PD0 as output
 PORTD.DIR = 0b00000001; 
 while(1) {
  // toggle and delay
  PORTD.OUTTGL = 0b00000001;
  _delay_ms(1000);
 }
 return 0;
}
{
    "build": {
      "f_cpu": "2000000L",
      "hwids": [
        [
          "0x1234",
          "0x0013"
        ],
        [
          "0x4567",
          "0x0013"
        ]
      ],
      "mcu": "atxmega256a3u"
    },
    "hardware": {
      "oscillator": "internal"
    },
    "platforms": ["atmelavr"],
    "name": "atxmega256a3u",
    "upload": {
      "maximum_ram_size": 16384,
      "maximum_size": 262144,
      "protocol": "atmelice_pdi"
    },
    "url": "https://www.microchip.com/en-us/product/ATXMEGA256A3U",
    "vendor": "Microchip"
  }

Here is my current atxmega256a3u.h after fix errors. I used PDI interface programming in state of JTAG, it is only nedded two wire to flash and debug mcu.

Then I write this in my platformio.ini.

When I build project I got this message, all has compiled well.

Unfortunately, when I flash the microcontroller I got this error. Do you have any idea? The program has been written good but the verification has failed.

Finally I would like to performance a good configuration to debug microcontroller with Platformio aswell.

Thanks :slightly_smiling_face:

Ah, it probably needs an erase. Add

upload_flags = -e

to the platformio.ini.

Or rather, add it as a extra_flag in the board’s JSON file like

Ok, it’s working as expected.
Could you help me to configure a good performance to debug with ATMELICE in Platformio?

Thanks :slightly_smiling_face:
RAR.

Debugging AVR chips with debug adapters (using JTAG/PDI/UPDI/debugWire) with open-source tools is basically an unstable nightmare and not included in PlatformIO, for reasons explained in PIO Unified Debugger for AVR ¡ Issue #95 ¡ platformio/platform-atmelavr ¡ GitHub.

PlatformIO does have simulator tools included (simavr) and avr-stub, but these don’t seem to be applying to your chip.

The only tool that seems to be able to do PDI (which you seem to use?) with an Atmel-ICE is AVaRICE . You would have to compile it for your operating system from source (e.g. with MinGW64 / MSys2 under Windows). Once you have that program, you can check the options to see

> avarice --help
AVaRICE version 2.14svn20200906, Oct 16 2021 10:40:06

Usage: avarice [OPTION]... [[HOST_NAME]:PORT]

Options:
  -h, --help                  Print this message.
  -1, --mkI                   Connect to JTAG ICE mkI (default)
  -2, --mkII                  Connect to JTAG ICE mkII
  -3, --jtag3                 Connect to JTAGICE3 (Firmware 2.x)
  -4, --edbg                  Atmel-ICE, or JTAGICE3 (firmware 3.x), or EDBG Integrated Debugger
  -B, --jtag-bitrate <rate>   Set the bitrate that the JTAG box communicates
                                with the avr target device. This must be less
                                than 1/4 of the frequency of the target. Valid
                                values are 1000/500/250/125 kHz (mkI),
                                or 22 through 6400 kHz (mkII).
                                (default: 250 kHz)
  -C, --capture               Capture running program.
                                Note: debugging must have been enabled prior
                                to starting the program. (e.g., by running
                                avarice earlier)
  -c, --daisy-chain <ub,ua,bb,ba> Daisy chain settings:
                                <units before, units after,
                                bits before, bits after>
  -D, --detach                Detach once synced with JTAG ICE
  -d, --debug                 Enable printing of debug information.
  -e, --erase                 Erase target.
  -E, --event <eventlist>     List of events that do not interrupt.
                                JTAG ICE mkII and AVR Dragon only.
                                Default is "none,run,target_power_on,target_sleep,target_wakeup"
  -g, --dragon                Connect to an AVR Dragon rather than a JTAG ICE.
                                This implies --mkII, but might be required in
                                addition to --debugwire when debugWire is to
                                be used.
  -I, --ignore-intr           Automatically step over interrupts.
                                Note: EXPERIMENTAL. Can not currently handle
                                devices fused for compatibility.
  -j, --jtag <devname>        Port attached to JTAG box (default: /dev/avrjtag).
  -k, --known-devices         Print a list of known devices.
  -L, --write-lockbits <ll>   Write lock bits.
  -l, --read-lockbits         Read lock bits.
  -P, --part <name>           Target device name (e.g. atmega16)

  -r, --read-fuses            Read fuses bytes.
  -R, --reset-srst            External reset through nSRST signal.
  -V, --version               Print version information.
  -w, --debugwire             For the JTAG ICE mkII, connect to the target
                                using debugWire protocol rather than JTAG.
  -W, --write-fuses <eehhll>  Write fuses bytes.
  -x, --xmega                 AVR part is an ATxmega device, using JTAG.
  -X, --pdi                   AVR part is an ATxmega device, using PDI.
HOST_NAME defaults to 0.0.0.0 (listen on any interface).
":PORT" is required to put avarice into gdb server mode.

Example usage:
	avarice --jtag /dev/ttyS0 :4242
	avarice --dragon :4242

The first test would be whether avarice can connect to the chip through the Atmel-ICE at all. You’d probably have to use a command like

avarice --jtag3 --pdi :4444

If, and only if, that seems to indicated success, you can integrate in PlatformIO through the platformio.ini similiar as shown in here.

I see it, understood. It is a pitty that it cannot performance a debug scenario at all in platformio for AVR devices :face_holding_back_tears:
When I have time, I will try what you are saying. And if it will work I will posted it in this topic.

Thanks a lot :slightly_smiling_face:
RAR.

I am also trying to migrate a project from Microchip Studio to Visual Studio code and platformio.
The current board which I am using is equipped with an ATxmega128A4U-AU controller.
I have prepared a custom boards file. (See below)
It was a challenging struggle so far :wink:, but I managed it to get the code compiled.
Unfortunately the linker reports a problem with missing object files, although the file is present in this location:
C:\Users\User\.platformio\packages\toolchain-atmelavr\avr\lib\avrxmega7

Linking .pio\build\ATmega128\firmware.elf
c:/users/user/.platformio/packages/toolchain-atmelavr/bin/../lib/gcc/avr/7.3.0/../../../../avr/bin/ld.exe: cannot find crtatxmega128a4u.o: No such file or directory
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\ATmega128\firmware.elf] Error 1

I have already added additional build flags without success.

build_flags =
    ${common_env_data.build_flags}
    -I"include/config"
    -I"include"
    -L$PROJECT_PACKAGES_DIR/toolchain-atmelavr/avr/lib/avrxmega7
    -D BOARD=USER_BOARD
    -D IOPORT_XMEGA_COMPAT

Is there a chance to refer the missing object file to be linked to the output binary?
Thanks in advance.

Custom board file:

{
  "build": {
    "core": "MegaCore",
    "extra_flags": "-DARDUINO_AVR_ATxmega128a4u -D__AVR_ATxmega128A4U__ -D__AVR_DEVICE_NAME__=atxmega128a4u",
    "f_cpu": "16000000L",
    "mcu": "atxmega128a4u"
  },
  "bootloader":{
    "led_pin": "B5"
  },
  "debug": {
    "simavr_target": "atmega128"
  },
  "frameworks": [
    "arduino"
  ],
  "name": "ATxmega128a4u",
  "upload": {
    "maximum_ram_size": 8192,
    "maximum_size": 131072,
    "protocol": "arduino",
    "require_upload_port": true,
    "speed": 115200
  },
  "url": "https://www.microchip.com/wwwproducts/ATxmega128a4u",
  "vendor": "Microchip"
}
2 Likes

Try adding

platform_packages = 
	toolchain-atmelavr@1.50400.190710

to your platformio.ini.

Thank you very much for the quick and valueable reply.

That solved the issue.

Congrats on making it compile, I’m learning myself that this is no trivial effort.