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