mraardvark / pyupdi

Python UPDI driver for programming "new" tinyAVR and megaAVR devices
MIT License
210 stars 73 forks source link

Cannot write fuses at all #61

Open MarkR42 opened 3 years ago

MarkR42 commented 3 years ago

Hi,

The -fs option appears broken, at least for attiny 1-series devices,

Traceback (most recent call last):
  File "/home/mark/ve_poo/bin/pyupdi.py", line 182, in <module>
    _main()
  File "/home/mark/ve_poo/bin/pyupdi.py", line 109, in _main
    if not _process(nvm, args):
  File "/home/mark/ve_poo/bin/pyupdi.py", line 131, in _process
    if not _set_fuse(nvm, fusenum, value):
  File "/home/mark/ve_poo/bin/pyupdi.py", line 163, in _set_fuse
    nvm.write_fuse(fusenum, value)
  File "/home/mark/ve_poo/lib/python3.6/site-packages/updi/nvm.py", line 135, in write_fuse
    return self.application.write_fuse(fuse_address, fuse_data)
  File "/home/mark/ve_poo/lib/python3.6/site-packages/updi/application.py", line 406, in write_fuse_v0
    if not self.progmode:
AttributeError: 'UpdiApplication' object has no attribute 'progmode'
MarkR42 commented 3 years ago

Steps to reproduce:

pyupdi.py -d tiny1617 -c /dev/ttyUSB0 -fs 128:0x2a

JohnHay commented 3 years ago

Mark, I also had the problem, so I tried your version. It did not give the python error anymore, but failed to program the fuse. It turns out that device.fuses_address is added twice. Once in updi/application.py write_fuse_v0() and also in updi/nvm.py write_fuse(). Removing one of them fixed it.

My command line: pyupdi.py -d tiny402 -c /dev/cuaU1 -fs 5:0xF7

mraardvark commented 3 years ago

First - sorry for all the mess :/ I have had little spare time to work on this lately (a busy summer) and added 24-bit DA support in haste (still has to be implemented properly) and forgot that fuse programming had been added. Secondly, you might be interested in trying pymcuprog which can read/write all memory areas using edbg-based debuggers as well as serial port (like pyupdi) (pip install pymcuprog)

a7hybnj2 commented 3 years ago

@mraardvark can you give a example of pymcuprog? I am trying to use my raspi0w as the tool. my pyupdi works for pyupdi.py -d tiny3216 -c /dev/serial0 --readfuses

pymcuprgm -u /dev/serial0 -i updi -d tiny3216 ping = Connecting to anything possible; ERROR: No CMSIS-DAP devices found.; Unable to connect to USB device I get the same for pymcuprog -s /dev/serial0 -i updi -d tiny3216 ping = Connecting to any tool with serial /dev/serial0'; ERROR: No CMSIS-DAP devices found.; Unable to connect to USB device

mraardvark commented 3 years ago

Yupp, its a tad confusing since "pyupdi" is embedded and thus the "tool" is "uart" with -u specifying which port: eg: pymcuprog ping -t uart -u /dev/tty.usbmodemFA132 -d atmega4808

a7hybnj2 commented 3 years ago

@mraardvark Thanks for the fast reply looks like my chip isn't in the supported list

~ ▶︎︎ pymcuprog ping -t uart -u /dev/serial0 -d attiny3216
Unable to setup stack for device attiny3216
Currently supported devices (in 'devices' folder):
avr128da48, uc3a3256, attiny416, atmega4809, pic16f15244, pic18f57q43, pic16f18446, avr128da28, pic16f1779, pic18f16q40, attiny1607, attiny3217, pic16f18456, atsamd21g18a, attiny1627, pic18f47q10, atmega328p, pic18f57q84, atmega4808, attiny84a, avr128db48, pic18f47k42, pic18f47k40, attiny817, pic16f15376, pic18f16q41, pic24fj128ga705, pic16lf18456, pic16f1768, pic18f47q43, atsamd21e18a
~ ▶︎︎ 

Anything I can add to fix this?

mraardvark commented 3 years ago

Oh dear. Until we get those devices in the package, you can have a crack at hacking it by locating the devices folder in your python site-packages and copy/rename the 3217.py...

a7hybnj2 commented 3 years ago

@mraardvark anyway to import the config that pyupdi uses since 3216 is supported there?

mraardvark commented 3 years ago

No unfortunately the format is very different. Another option might be to download the wheel from pypi, modify it and install locally... (I am hoping to update the devices in the next few weeks.)

a7hybnj2 commented 3 years ago

so in my .local/lib/python3.7/site-packages/device/device.py

~/.l/l/p/s/device ▶︎︎ cat device.py | grep 3217
DEVICES_TINY_32K = set(["tiny3216", "tiny3217"])

That looks like 3216 is already set for something.

I don't see a 3217.py anywhere nor does `sudo find / -name 3217' return anything.

I also looked for a site package in /usr/lib but those were all dist packages

EDIT: I think I found it

a7hybnj2 commented 3 years ago

How does this look? I just changed the device ID. I hope it doesn't brick my chip..

~/.l/l/p/s/p/d/devices ▶︎︎ cat attiny3216.py 
"""
Required device info for the ATtiny3217 devices
"""
from pymcuprog.deviceinfo.eraseflags import ChiperaseEffect

DEVICE_INFO = {
    'name': 'attiny3217',
    'architecture': 'avr8x',

    # eeprom
    'eeprom_address_byte': 0x00001400,
    'eeprom_size_bytes': 0x0100,
    'eeprom_page_size_bytes': 64,
    'eeprom_read_size_bytes': 1,
    'eeprom_write_size_bytes': 1,
    'eeprom_chiperase_effect': ChiperaseEffect.CONDITIONALLY_ERASED_AVR,
    'eeprom_isolated_erase': True,

    # fuses
    'fuses_address_byte': 0x00001280,
    'fuses_size_bytes': 0xA,
    'fuses_page_size_bytes': 1,
    'fuses_read_size_bytes': 1,
    'fuses_write_size_bytes': 1,
    'fuses_chiperase_effect': ChiperaseEffect.NOT_ERASED,
    'fuses_isolated_erase': False,

    # internal_sram
    'internal_sram_address_byte': 0x3800,
    'internal_sram_size_bytes': 0x0800,
    'internal_sram_page_size_bytes': 1,
    'internal_sram_read_size_bytes': 1,
    'internal_sram_write_size_bytes': 1,
    'internal_sram_chiperase_effect': ChiperaseEffect.ALWAYS_ERASED,
    'internal_sram_isolated_erase': False,

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

    # flash
    'flash_address_byte': 0x00008000,
    'flash_size_bytes': 0x8000,
    'flash_page_size_bytes': 0x80,
    'flash_read_size_bytes': 2,
    'flash_write_size_bytes': 2,
    'flash_chiperase_effect': ChiperaseEffect.ALWAYS_ERASED,
    # Separate flash erase is supported by the device but not by pymcuprog
    'flash_isolated_erase': False,

    # signatures
    'signatures_address_byte': 0x00001100,
    'signatures_size_bytes': 0x3,
    'signatures_page_size_bytes': 0x80,
    'signatures_read_size_bytes': 1,
    'signatures_write_size_bytes': 0,
    'signatures_chiperase_effect': ChiperaseEffect.NOT_ERASED,
    'signatures_isolated_erase': False,

    # user_row
    'user_row_address_byte': 0x00001300,
    'user_row_size_bytes': 0x40,
    'user_row_page_size_bytes': 0x40,
    'user_row_read_size_bytes': 1,
    'user_row_write_size_bytes': 1,
    '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,
    'interface': 'UPDI',
    'device_id': 0x1E9521,
}
mraardvark commented 3 years ago

Should only need a new ID, correct. But I would rather make a dedicated mega3216.py copied and modified from the 3217.

mraardvark commented 3 years ago

Well? Do you have a brick? :|

a7hybnj2 commented 3 years ago

@mraardvark No! I am brick free! I am able to read and write fuses. I am still using pyupdi for writing the flash though.

it seems like this pymcuprog is capable of writing flash also, any reason I should switch or stay with pyupdi? pros, cons?

Thanks for the very timely support today it was much appreciated.

mraardvark commented 3 years ago

Good to hear! I would use pymcuprog, but it has its drawbacks. Here are some arguments: (+) pymcuprog hasan installer (pip install pymcuprog) (+) pymcuprog can write all mem types in the device file, lock, unlock etc (+) pymcuprog can be used as a CLI (for quick operations) as well as library (for building into production lines etc) (+) pymcuprog with a USB tool can also be much faster (eg buy a cnano and saw it in half) (+) pymcuprog is better tested than pyupdi (+-) pymcuprog has a wide range of uses, some of which are not-developed stubs (+) pyupdi has source published, so you can fork and customise (eg: high-voltage adapters) (+) pyupdi you can add your own devices immediately

a7hybnj2 commented 3 years ago

I have some things I ran into with pymcuprog. Should I move over to https://github.com/mraardvark/pymcuprog/issues ?

mraardvark commented 3 years ago

Sure. Its not quite the right place, but a good enough place to start 👍

Jeff384 commented 3 years ago

Hello,

I submitted a pull request that fixed the fuse setting problem with pyupdi, at least for the tiny1606/7 devices, which is all I have to test against. Hopefully it works for everyone.

-Jeff

mraardvark commented 3 years ago

Super! Thanks @Jeff384 As mentioned somewhere up here - I have little to no test capacity here (hence the pymcuprog path).