Problems Migrating From Studio 7 to PlatformIO (ATtiny402 with pymcuprog custom tool)

I have successfully used PYMCUPROG with a modified USB to Serial adapter from Studio 7 acting as an External Tool.

I can’t get platformio.ini set up to run the SerialUPDI successfully.

Here’s some details: My source code (same used on Studio 7 and PlatformIO)

/*
 * ATtiny402LowPowerRunning.c
 * These settings (F_CPU 32000UL, 0 prescaler, all GPIOs apart from LED pin set to pullup inc UPDI, force OSC20M off)
 * Result in a processor current draw of 16uA!
 * Created: 05/05/2019 20:46:56
 * Author : Simon
 */ 

#ifndef F_CPU
#define F_CPU 32000UL // 32 kHz clock speed / 0 prescaler divisor
#endif

#include <util/delay.h>	// needed for our delay
#include <avr/io.h>
// #include <Arduino.h>

int main(void){

	/* Set the Main clock to internal 32kHz oscillator*/
	_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSCULP32K_gc);
	/* Set the Main clock prescaler divisor to 2X and disable the Main clock prescaler */
	_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc); // without enable
	/* ensure 20MHz isn't forced on*/
	_PROTECTED_WRITE(CLKCTRL.OSC20MCTRLA, 0x00);

	/* Configure Port A, Pin 6 as an output (remember to connect LED to PB6 and use a resistor in series to GND)*/
	PORTA.DIRSET = PIN6_bm;
	
	/* Set all pins except the LED pin to pullups*/
	PORTA.PIN0CTRL = PORT_PULLUPEN_bm;
	PORTA.PIN1CTRL = PORT_PULLUPEN_bm;
	PORTA.PIN2CTRL = PORT_PULLUPEN_bm;
	PORTA.PIN3CTRL = PORT_PULLUPEN_bm;
	//PORTA.PIN6CTRL = PORT_PULLUPEN_bm; // LED pin
	PORTA.PIN7CTRL = PORT_PULLUPEN_bm;
	
	
	while (1)	{
		// PAUSE 1000 milliseconds
		_delay_ms(1);
		
		// LED off
		PORTA.OUTCLR = PIN6_bm;
		
		// PAUSE 2000 milliseconds
		_delay_ms(2);
		
		// LED on
		PORTA.OUTSET = PIN6_bm;
	}
}

The Platformio.ini

; 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

[env:ATtiny402]
platform = atmelmegaavr
board = ATtiny402
framework = arduino
upload_protocol = custom

upload_speed = 115200
upload_flags =
    --tool
    uart
    --device
    ATtiny402w
    --uart
    $UPLOAD_PORT
    --clk
    $UPLOAD_SPEED
upload_command = pymcuprog write --erase $UPLOAD_FLAGS --filename $SOURCE
; upload_command = pymcuprog write --erase --tool uart --clk 115200 --uart COM12 --device ATtiny402w --filename "D:\Users\Peter\Documents\PlatformIO\Projects\ATtiny402_Test\.pio\build\ATtiny402\firmware.hex"

When I run PYMCUPROG from command line, I get the following results:
For PlatformIO

C:\Users\Peter>pymcuprog write --erase --tool uart --clk 115200 --uart COM12 --device ATtiny402w --filename "D:\Users\Peter\Documents\PlatformIO\Projects\ATtiny402_Test\.pio\build\ATtiny402\firmware.hex"
Connecting to SerialUPDI
Pinging device...
Ping response: 1E9221
Erasing device before writing from hex file...
Writing from hex file...
Writing flash...
Done.

and for Studio 7

C:\Users\Peter>pymcuprog write --erase --tool uart --clk 115200 --uart COM12 --device ATtiny402w --filename "C:\Users\Peter\Documents\Atmel Studio\7.0\ATtiny402Demo\ATtiny402Demo\Debug\ATtiny402Demo.hex"
Connecting to SerialUPDI
Pinging device...
Ping response: 1E9221
Erasing device before writing from hex file...
Writing from hex file...
Writing flash...
Done.

So the hex files themselves are syntactically fine - a quick note about the ATtiny402w - my ATtiny402 chip returns the wrong device ID so I had to build a custom python script file for the part - I modified the Attiny402.py and called it Attiny402w.py and it’s contents are here:


"""
Required device info for the attiny402 devices
The following data was collected from device pack Microchip.ATtiny_DFP 3.0.138
"""

from pymcuprog.deviceinfo.eraseflags import ChiperaseEffect

DEVICE_INFO = {
    'interface': 'UPDI',
    'name': 'attiny402',
    'architecture': 'avr8x',

    # eeprom
    'eeprom_address_byte': 0x00001400,
    'eeprom_size_bytes': 0x0080,
    'eeprom_page_size_bytes': 0x20,
    'eeprom_read_size_bytes': 0x01,
    'eeprom_write_size_bytes': 0x01,
    'eeprom_chiperase_effect': ChiperaseEffect.CONDITIONALLY_ERASED_AVR,
    'eeprom_isolated_erase': True,

    # flash
    'flash_address_byte': 0x00008000,
    'flash_size_bytes': 0x1000,
    'flash_page_size_bytes': 0x40,
    'flash_read_size_bytes': 0x02,
    'flash_write_size_bytes': 0x40,
    'flash_chiperase_effect': ChiperaseEffect.ALWAYS_ERASED,
    'flash_isolated_erase': True,

    # fuses
    'fuses_address_byte': 0x1280,
    'fuses_size_bytes': 0x09,
    'fuses_page_size_bytes': 0x01,
    'fuses_read_size_bytes': 0x01,
    'fuses_write_size_bytes': 0x01,
    'fuses_chiperase_effect': ChiperaseEffect.NOT_ERASED,
    'fuses_isolated_erase': False,

    # internal_sram
    'internal_sram_address_byte': 0x3f00,
    'internal_sram_size_bytes': 0x0100,
    'internal_sram_page_size_bytes': 0x01,
    'internal_sram_read_size_bytes': 0x01,
    'internal_sram_write_size_bytes': 0x01,
    'internal_sram_chiperase_effect': ChiperaseEffect.NOT_ERASED,
    'internal_sram_isolated_erase': False,

    # lockbits
    'lockbits_address_byte': 0x0000128A,
    'lockbits_size_bytes': 0x1,
    'lockbits_page_size_bytes': 0x01,
    'lockbits_read_size_bytes': 0x01,
    'lockbits_write_size_bytes': 0x01,
    'lockbits_chiperase_effect': ChiperaseEffect.ALWAYS_ERASED,
    'lockbits_isolated_erase': False,

    # signatures
    'signatures_address_byte': 0x1100,
    'signatures_size_bytes': 0x40,
    'signatures_page_size_bytes': 0x01,
    'signatures_read_size_bytes': 0x01,
    'signatures_write_size_bytes': 0x00,
    'signatures_chiperase_effect': ChiperaseEffect.NOT_ERASED,
    'signatures_isolated_erase': False,

    # user_row
    'user_row_address_byte': 0x1300,
    'user_row_size_bytes': 0x20,
    'user_row_page_size_bytes': 0x20,
    'user_row_read_size_bytes': 0x01,
    'user_row_write_size_bytes': 0x01,
    'user_row_chiperase_effect': ChiperaseEffect.NOT_ERASED,
    'user_row_isolated_erase': True,

    # Some extra AVR specific fields
    'nvmctrl_base': 0x00001000,
    'syscfg_base': 0x00000F00,
    'ocd_base': 0x00000F80,
    'prog_clock_khz': 900,
    'address_size': '16-bit',
    'hv_implementation': 0,
    'device_id': 0x1E9221,
    # was 'device_id': 0x1E9227,

}

(As a side note, using an Arduino as a jtag2updi programmer also worked from Studio 7 but we’re supposed to be moving away from jtag2updi.)

My issue relates to failing to get PlatformIO to run the Upload command - when I do I get the following error although I may run the same command successfully from a command line (as above).

Error message is:

Processing ATtiny402 (platform: atmelmegaavr; board: ATtiny402; framework: arduino)
----------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelmegaavr/ATtiny402.html
PLATFORM: Atmel megaAVR (1.6.0) > ATtiny402
HARDWARE: ATTINY402 16MHz, 256B RAM, 4KB Flash
PACKAGES:
 - framework-arduino-megaavr-megatinycore @ 2.5.11
 - tool-avrdude-megaavr @ 3.60300.220118 (6.3.0)
 - toolchain-atmelavr @ 3.70300.220127 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 15 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Compiling .pio\build\ATtiny402\src\main.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\Tone.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\UART.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\UART0.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\UART1.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\WInterrupts.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\WInterrupts_PA.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\WInterrupts_PB.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\WInterrupts_PC.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\WMath.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\abi.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\api\Common.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\api\IPAddress.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\api\PluggableUSB.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\api\Print.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\api\RingBuffer.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\api\Stream.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\api\String.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\hooks.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\main.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\new.cpp.o
Compiling .pio\build\ATtiny402\FrameworkArduino\wiring.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\wiring_analog.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\wiring_digital.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\wiring_pulse.S.o
Compiling .pio\build\ATtiny402\FrameworkArduino\wiring_pulse.c.o
Compiling .pio\build\ATtiny402\FrameworkArduino\wiring_shift.c.o
Archiving .pio\build\ATtiny402\libFrameworkArduino.a
Linking .pio\build\ATtiny402\firmware.elf
Checking size .pio\build\ATtiny402\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   0.0% (used 0 bytes from 256 bytes)
Flash: [          ]   4.2% (used 174 bytes from 4096 bytes)
Building .pio\build\ATtiny402\firmware.hex
Configuring upload protocol...
AVAILABLE: custom
CURRENT: upload_protocol = custom
Uploading .pio\build\ATtiny402\firmware.hex
Fatal Python error: init_import_size: Failed to import the site module
Python runtime state: initialized
Traceback (most recent call last):
  File "C:\Users\Peter\.platformio\python3\lib\site.py", line 73, in <module>
    import os
  File "C:\Users\Peter\.platformio\python3\lib\os.py", line 29, in <module>
    from _collections_abc import _check_methods
  File "C:\Users\Peter\.platformio\python3\lib\_collections_abc.py", line 12, in <module>
    GenericAlias = type(list[int])
TypeError: 'type' object is not subscriptable
*** [upload] Error 1
================================================= [FAILED] Took 4.70 seconds =======================
 *  The terminal process "C:\Users\Peter\.platformio\penv\Scripts\platformio.exe 'run', '--target', exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it. 

You can see from my platformio.ini that I attempted to put the command in ‘long hand’ just to make sure it was not a macro issue - but this has the same issue.

Any ideas?

I’d love to migrate to PlatformIO as it is supposed to have a fuse calculator which is unavailable to me using an external tool (UPDI programmer) on Studio 7. I also believe PlatformIO handles Arduino libraries which is not the case with Studio 7.

I apologise if this all seems trivial - I’m real new to PlatformIO and just trying to get started.

Best regards
Peter

Digging a bit deeper into the error code, there were two reported problems in the site.py file:

Import "sitecustomize" could not be resolved
Import "usercustomize" could not be resolved

os.py has 38 errors - maybe too many to paste here - something’s ‘broke’ but I don’t know what.

I am sorry I do not understand the significance of this.

Weird how a simple impot os can fail that badly.

Can you try uninstalling your pymcuprog from your global python environment (which you must have if pymcuprog works directly on the commandline) and install it again in PlatformIO’s virtual environment? This is, in the pip you get in the PlatformIO CLI.

Hi Max - I’ll certainly try that to fix the tool issue.
I think I know why my _delay_ms() timings are off.
In Studio 7, I do not have the Dr Azzy Arduino framework (great work), just the Atmel ‘plug in’ to describe the device. It must be my conditional compile round my #define F_CPU statement. Somewhere in the PlatformIO Arduino framework, F_CPU must already be defined as 20000000UL (20MHz). The code I am using (I didn’t write it) is controlling the ATtiny402 clock and this must be working OK. With an actual clock at 32kHz but being counted as if it were running at 20MHz is going to appear to be 625 times slower.
I have to fess up - I’m a newbie to the series 0 and 1 Atmel ATtiny chips - I want to use them for their v low power, I want to leverage on their events RTC in place of having to use a watch dog timer to wake up my ‘old’ Attiny85 and I’m just trying to get started with a simple blinky.
I’ll update the original post accordingly.

You can control the value of the F_CPU macro by telling PlatformIO your clock speed, as documented in

; 2 MHz
board_build.f_cpu = 2000000L

Hi Max
I used a command line to uninstall pymcuprog as below

C:\Users\Peter>pip uninstall pymcuprog
Found existing installation: pymcuprog 3.13.3.166
Uninstalling pymcuprog-3.13.3.166:
  Would remove:
    d:\users\peter\appdata\local\programs\python\python38\lib\site-packages\pymcuprog-3.13.3.166.dist-info\*
    d:\users\peter\appdata\local\programs\python\python38\lib\site-packages\pymcuprog\*
    d:\users\peter\appdata\local\programs\python\python38\scripts\pymcuprog.exe
  Would not remove (might be manually added):
    d:\users\peter\appdata\local\programs\python\python38\lib\site-packages\pymcuprog\deviceinfo\devices\attiny402w.py
Proceed (Y/n)? y
  Successfully uninstalled pymcuprog-3.13.3.166

I opened up Terminal | New Terminal from PlatformIO as below:

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS D:\Users\Peter\Documents\PlatformIO\Projects\ATtiny402_Test> cd..
PS D:\Users\Peter\Documents\PlatformIO\Projects> cd..
PS D:\Users\Peter\Documents\PlatformIO> pip install pymcuprog
Collecting pymcuprog
   Using cached pymcuprog-3.13.3.166-py3-none-any.whl (221 kB)
Requirement already satisfied: pyyaml in d:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from pymcuprog) (6.0)
Requirement already satisfied: intelhex in d:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from pymcuprog) (2.3.0)
Requirement already satisfied: pyserial in d:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from pymcuprog) (3.5)
Requirement already satisfied: appdirs in d:\users\peter\appdata\local\programs\python\python38\lib\site-packages (frRequirement already satisfied: pyedbglib>=2.20 in d:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from pymcuprog) (2.20.3.105)                                                 n38\lib\site-pack
Requirement already satisfied: cython in d:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from pyedbglib>=2.20->pymcuprog) (0.29.32)                                            ite-packages (fro
Requirement already satisfied: hidapi in d:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from pyedbglib>=2.20->pymcuprog) (0.12.0.post2)                                       ite-packages (fro
Requirement already satisfied: setuptools>=19.0 in d:\users\peter\appdata\local\programs\python\python38\lib\site-packages (from hidapi->pyedbglib>=2.20->pymcuprog) (41.2.0)                           on38\lib\site-pac
Installing collected packages: pymcuprog
Successfully installed pymcuprog-3.13.3.166

I get the same error trying to upload code to my device:

Uploading .pio\build\ATtiny402\firmware.hex
Fatal Python error: init_import_size: Failed to import the site module
Python runtime state: initialized
Traceback (most recent call last):
  File "C:\Users\Peter\.platformio\python3\lib\site.py", line 73, in <module>
    import os
  File "C:\Users\Peter\.platformio\python3\lib\os.py", line 29, in <module>
    from _collections_abc import _check_methods
  File "C:\Users\Peter\.platformio\python3\lib\_collections_abc.py", line 12, in <module>
    GenericAlias = type(list[int])
TypeError: 'type' object is not subscriptable
*** [upload] Error 1

Could it be caused by the PlatformIO PS install of pymcuprog was “Using cached pymcuprog-3.13.3.166-”?

Not sure what to try next - any ideas gratefully welcome.

Hi Max - regarding the F_CPU macro. Thanks for the pointer - I can use this to set the F_CPU to as low as 1MHz as below:

[env:ATtiny402]
platform = atmelmegaavr
board = ATtiny402
; change MCU frequency
board_build.f_cpu = 1000000L
framework = arduino
upload_protocol = custom
upload_speed = 115200

But I get a nasty error when I try to define it as 32kHz

C:\Users\Peter\.platformio\packages\framework-arduino-megaavr-megatinycore\cores\megatinycore\wiring.c: In function 'micros':
C:\Users\Peter\.platformio\packages\framework-arduino-megaavr-megatinycore\cores\megatinycore\wiring.c:694:48: error: division by zero in #if
         #if (TIME_TRACKING_TIMER_DIVIDER%(F_CPU/1000000))
                                                ^
Compiling .pio\build\ATtiny402\FrameworkArduino\wiring_shift.c.o
C:\Users\Peter\.platformio\packages\framework-arduino-megaavr-megatinycore\cores\megatinycore\wiring.c: In function 'init_clock':
C:\Users\Peter\.platformio\packages\framework-arduino-megaavr-megatinycore\cores\megatinycore\wiring.c:1344:12: error: #error "F_CPU defined as an unsupported value for untuned internal oscillator"   
           #error "F_CPU defined as an unsupported value for untuned internal oscillator"
            ^~~~~
*** [.pio\build\ATtiny402\FrameworkArduino\wiring.c.o] Error 1
==================================== [FAILED] Took 3.93 seconds ====================================

However, if I just take out the conditional on my compile

//#ifndef F_CPU
#define F_CPU 32000UL // 32 kHz clock speed / 0 prescaler divisor
//#endif

the _delay_ms(1000); gives me a fairly accurate 1s delay and no compile errors. ???

Hi Max Issue with pymcuprog - I found this link SpenceKonde/megaTinyCore
Maybe my instance of Python3 is in the wrong place - I’ll try following this post.

Hi Max - Issue with PYMCUPROG
I uninstalled a bunch of stuff including pymcuprog, python, Arduino 1.8 and set about trying to get things going again.
I have succeeded in programming ATtiny402 from Arduino IDE using Spence Konde’s megaTinyCore via a modified serial adapter - I had to add a modified device file into C:\Users\Peter\AppData\Local\Arduino15\packages\megaTinyCore\hardware\megaavr\2.5.11\tools\libs\pymcuprog\deviceinfo\devices

To get Studio 7 to upload successfully with the modified serial adapter, I had to add a modified device file into D:\Users\Peter\AppData\Local\Programs\Python\Python310\Lib\site-packages\pymcuprog\deviceinfo\devices

OK - no consistency with drives - I was just trying different things.

I used the PlatformIO terminal to install an instance of pymcuprog

PS D:\Users\Peter\Documents\PlatformIO\Projects\ATtiny402_Test> pip install pymcuprog
Requirement already satisfied: pymcuprog in d:\users\peter\appdata\local\programs\python\python310\l
(3.13.3.166)
Requirement already satisfied: pyedbglib>=2.20 in d:\users\peter\appdata\local\programs\python\pythokages (from pymcuprog) (2.20.3.105)
Requirement already satisfied: intelhex in d:\users\peter\appdata\local\programs\python\python310\lifrom pymcuprog) (2.3.0)
Requirement already satisfied: pyserial in d:\users\peter\appdata\local\programs\python\python310\lifrom pymcuprog) (3.5)
Requirement already satisfied: appdirs in d:\users\peter\appdata\local\programs\python\python310\librom pymcuprog) (1.4.4)
og) (0.29.32)
Requirement already satisfied: setuptools>=19.0 in d:\users\peter\appdata\local\programs\python\python310\lib\site-packages (from hidapi->pyedbglib>=2.20->pymcuprog) (63.2.0)

[notice] A new release of pip available: 22.2.1 -> 22.2.2
[notice] To update, run: python.exe -m pip install --upgrade pip
PS D:\Users\Peter\Documents\PlatformIO\Projects\ATtiny402_Test>

The output from the upload attempt has changed but is still throwing an error about a missing dll

RAM:   [          ]   0.0% (used 0 bytes from 256 bytes)
Flash: [          ]   4.0% (used 162 bytes from 4096 bytes)
Building .pio\build\ATtiny402\firmware.hex
Configuring upload protocol...
AVAILABLE: custom
CURRENT: upload_protocol = custom
Uploading .pio\build\ATtiny402\firmware.hex
Traceback (most recent call last):
  File "C:\Users\Peter\.platformio\python3\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\Peter\.platformio\python3\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "D:\Users\Peter\AppData\Local\Programs\Python\Python310\Scripts\pymcuprog.exe\__main__.py", line 4, in <module>
  File "D:\Users\Peter\AppData\Local\Programs\Python\Python310\lib\site-packages\pymcuprog\pymcuprog.py", line 12, in <module>
    from logging.config import dictConfig
  File "C:\Users\Peter\.platformio\python3\lib\logging\config.py", line 30, in <module>
    import logging.handlers
  File "C:\Users\Peter\.platformio\python3\lib\logging\handlers.py", line 26, in <module>
    import logging, socket, os, pickle, struct, time, re
  File "C:\Users\Peter\.platformio\python3\lib\socket.py", line 51, in <module>
    import _socket
ImportError: DLL load failed while importing _socket: The specified module could not be found.      
*** [upload] Error 1
==================================== [FAILED] Took 4.70 seconds ====================================
 *  The terminal process "C:\Users\Peter\.platformio\penv\Scripts\platformio.exe 'run', '--target', 'upload'" terminated with exit code: 1.

Are you able to help?

Incidentally I am still able to upload my PlatformIO hex file from a command line

C:\Users\Peter>pymcuprog write --erase --tool uart --clk 115200 --uart COM12 --device ATtiny402w --filename "D:\Users\Peter\Documents\PlatformIO\Projects\ATtiny402_Test\.pio\build\ATtiny402\firmware.hex"
Connecting to SerialUPDI
Pinging device...
Ping response: 1E9221
Erasing device before writing from hex file...
Writing from hex file...
Writing flash...
Done.

It’s still going in your global Python 310 installation when PlatformIO is supposed to be running of its isolated environment.

Please pip uninstall pymcuprog again and in the PlatformIO CLI, execute pio system info. It will show a line with

Python Executable           c:\users\max\....\python.exe

Use the full path to that shown python executable and append -m pip install pymcuprog after it to install it. Then retry uploading.

Hi Max
Many thanks. pymcuprog seems to be flying now.
Making progress now - errors now relate to the duff board ID - I think I may be able to work around this by defining a new device file.
The $UPLOAD_PORT macro in the platformio.ini doesn’t seem to work - the error something like --uart expects a parameter - seems to imply it returns blank. If I hard code my com port, this error goes away. I can work round this.

Success!
I have end to end functionality. :grinning: I had to pop a new attiny402w.py into C:\Users\Peter\.platformio\penv\Lib\site-packages\pymcuprog\deviceinfo\devices
Thank you so much for sticking with me.
Now I just need to learn how to program these new MCUs.

RAM:   [          ]   0.0% (used 0 bytes from 256 bytes)
Flash: [          ]   4.0% (used 162 bytes from 4096 bytes)
Configuring upload protocol...
AVAILABLE: custom
CURRENT: upload_protocol = custom
Uploading .pio\build\ATtiny402\firmware.hex
Connecting to SerialUPDI
Pinging device...
Ping response: 1E9221
Erasing device before writing from hex file...
Writing from hex file...
Writing flash...
Done.