Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PICkit 5 support #1863

Merged
merged 38 commits into from
Aug 14, 2024
Merged

PICkit 5 support #1863

merged 38 commits into from
Aug 14, 2024

Conversation

MX682X
Copy link
Contributor

@MX682X MX682X commented Aug 2, 2024

Alright, should be complete now, or at least complete enough for experimental release.
Supports: Writing and reading of all memories, chip erase, Setting Baudrate (which is the UPDI Baudrate in this case), Supplying Power through "-xvoltage="[mV]

As the PICkit5 can read and write arbitrary amounts, I've added read_array()/write_array() functions, allowing a significant reduction in overhead, compared to single byte reads/writes of e.g. SRAM

When testing the terminal mode, I noticed that some functions were checking "rc" against non zero after byte reads, which didn't make sense for me, as the read functions are allowed to return number of read bytes (meaning returning 1 for 1 byte read was treated as error), so I decided to change it to check against negative rc

Oh, and one more thing:
I haven't programmed much for OS based systems, so I can't tell if it's bad or not: There are some functions, where I declare a small local array and pass it as pointer to another function. So far, no problem my test, but I can imagine it might cause Problems. Any suggestions on that topic?

@mcuee mcuee added the enhancement New feature or request label Aug 3, 2024
@stefanrueger
Copy link
Collaborator

Brilliant @MX682X

We'll have to carefully review and test.

I have just quickly scrolled through the code and it looks competently written.

One thing I noted is that the read_array() function in term.c bypasses the terminal cache. That's bound to end in tears. The model is that the terminal only every uses byte-wise cached r/w functions, which in turn will deploy paged_load() and paged_write() functions of the programmer (if memory is paged) to fill the cache. The terminal code is programmer-agnostic and, ideally, term.c should not need to be touched when a new programmer is integrated into AVRDUDE.

But yes, vvv pleased to have a pickit5 implementation. With a bit of fair wind we could get that into v 8.0.

@stefanrueger
Copy link
Collaborator

some functions, where I declare a small local array and pass it as pointer to another function

OK, as long as the pointer to the local array on the stack is passed down to callees and not returned to callers. Do you want to share an example?

@MX682X
Copy link
Contributor Author

MX682X commented Aug 3, 2024

Ok, so MacOS rellay needs usbhid and can't compile with libusb.... this is bad, because from what I know I have to talk to the Specific Endpoints
1 (Read command response),
2 (Command write),
3 (Data channel for memory read)
4 (Data channel for memory write)
and I didn't see usbhid offering a way to specify the EP the data is sent to/read from.
This is even the reason why I copy-pasted the libusb transfer functions but with different endpoints...

I could try to figure out what they doing in fruit-land, if anyone with MacOS, MPLAB and Wireshark could send me the capture files.
I'm afraid though, that they are just requiring libusb to be installed and there won't be any useful information.

OK, as long as the pointer to the local array on the stack is passed down to callees and not returned to callers. Do you want to share an example?

https://github.com/MX682X/avrdude/blob/88e78565125102ff27158c050dbecbdbd1e4043a/src/pickit5.c#L829
https://github.com/MX682X/avrdude/blob/88e78565125102ff27158c050dbecbdbd1e4043a/src/pickit5.c#L751

which in turn will deploy paged_load() and paged_write() functions of the programmer (if memory is paged) to fill the cache.

The whole thing was an attempt at optimization. The way the reading is done is that the start address and the length is transmitted to the PICkit and it runs the for-loop internally and sends the data back in one chunk. Requesting only one byte at a time creates a significant overhead on the USB side I'm trying to avoid. At least when it comes to Unpaged memory like SRAM or EEPROM, and it seemed like that if there is no paging, avrdude won't allow reading multiple bytes.
To be fair, I haven't benchmarked the byte-by-byte approach, so i can't tell how much it really slows it down.
Also, this means that the Progressbar is always 0% or 100% on unpaged memories, but I doubt this will be problematic

@stefanrueger
Copy link
Collaborator

@MX682X Your examples with usage of local arrays are standard and good practice.

Unpaged memory like SRAM or EEPROM

They are only treated as unpaged if their page_size entry in avrdude.conf is 1. If it's a power of two that divides the memory size and there are paged_load() and paged_write() functions in the driver they get normally called (the memory paged property is actually only relevant for flash for some historic reasons). SRAM isn't really relevant for AVRDUDE as it's volatile. It is mainly used for the disassembler to know where memory is.

Surprisingly, many AVRnnDxmm parts have an EEPROM size of 1. Type the following to see them:

$ avrdude -p */At | grep eeprom.page_size | grep 1$

This may or may not be needed. I don't know why that is!

You could try to overwrite page_size for SRAM and EEPROM at a suitable place in your driver. I suggest pickit5_enable(), which is the first of the programmer functions that sees the part:

  // Set page size to 64 to ensure paged load and paged write
  AVRMEM *mem;
  if((mem = avr_locate_sram(p)))
    mem->page_size = mem->size < 64? mem->size: 64;
  if((mem = avr_locate_eeprom(p)))
    mem->page_size = mem->size < 64? mem->size: 64;

This will ensure the paged_load() and paged_write() functions are called instead of the byte-wise functions for -U and for terminal EEPROM (through the cache). The terminal doesn't cache SRAM so that might still be slow as that's indeed accessed byte by byte there. It's not really useful and I don't have a use case why users would want to see SRAM in AVRDUDE (other than because they can).

To cut a long short: please don't change term.c; don't furnish the programmer with yet another set of read/write functions; build back array_read and array_write

Did I say that it's exciting to have pickit5 in AVRDUDE? Brilliant stuff. I will review and help fold your code into AVRDUDE with a view that it fits with the philosophy and can be maintained by us. Please bear with me.

@MX682X MX682X reopened this Aug 3, 2024
@MX682X
Copy link
Contributor Author

MX682X commented Aug 3, 2024

Sorry for the closing/reopening, still figuring out git...
Anyway, I've removed all the changes related to read/write_array outside of the driver. Also added the page_size overwrite.

PS: I haven't touched the High Voltage Programming yet, so this feature s not supported yet

@MCUdude
Copy link
Collaborator

MCUdude commented Aug 3, 2024

Ok, so MacOS really needs usbhid and can't compile with libusb

@MX682X I don't quite get what the problem is with macOS and libusb/hidapi.
The Atmel ICE and PICkit4 work fine on macOS using hidapi. Is the problem that you can't use hidapi on macOS, and the way libusb is used with Avrdude makes it only supports full speed (USB 1.1) and not high-speed (USB 2.0)?

@MX682X
Copy link
Contributor Author

MX682X commented Aug 3, 2024

@MCUdude I need to write to specific Endpoints. I was not able to find a way to specify an endpoint in the usbhid files.
While digging, I even found this:
https://github.com/libusb/hidapi/blob/d101e5c7e4646ecde66b650b3b8ce4904acfb13a/hidapi/hidapi.h#L310

hid_write() will send the data on the first interrupt OUT endpoint, if one exists.

same goes for read. But now that I'm thinking about it, maybe it could work if there are two hid descriptors, the second being a copy, except for the Endpoints, which are changed? Could this work? But then again the whole ordeal fails as I have no way to test it.

@stefanrueger
Copy link
Collaborator

stefanrueger commented Aug 3, 2024

removed all the changes related to read/write_array outside of the driver

Excellent, @MX682X. It's now a much neater separation of programmer code and AVRDUDE infrastructure

A couple of things I noted whilst scrolling through the PR (without reading code)

  • The files scripts_lut.[ch] should be renamed pickit5_lut.[ch] (we have 53 programmer types with 167 programmers, names are important for us to find our way through the code)
  • Programmers should not use export/provide static/global variables with the exception of const read/only tables (that restriction is needed for projects using libavrdude). Hence PDATA(pgm) which you use (good!). Just from scrolling I think the code looks OK with this respect, but I've seen things like char *chip_lut[] which ought to be const char * const chip_lut[] (both the table is read/only as are the strings stored in it). Please carefully check all global tables and make sure they are const.
  • Namespaces: given the collection of many programmers global symbols such as chip_lut can be mildly disorienting for the maintainers. I'd suggest either #include the tables into pickit5.c and make them static or rename the tables to sth like pickit5_chip_lut if you prefer them compiled separately and linked.

Not sure when I have time for a proper review etc, but will be in next few days.

  • How invested are you in the formatting? It's OK if you are, but if you don't mind, and seeing that it's the initial commit, I'd (slightly) prefer running the code through an indent program with (current) AVRDUDE style
  • Is it OK if I push commits onto your branch, eg, smaller things, tricky points for AVRDUDE integration, or formatting?
  • Do you want (after all is done) a squash merge or one that keeps the individual commits?

@MCUdude
Copy link
Collaborator

MCUdude commented Aug 4, 2024

@MX682X so the reason for using libusb here is to be able to write to specific endpoints, which hidapi does not support. But the way libusb is implemented in usb_libusb.c, it doesn't work with high-speed USB, but only full-speed. Am I right?

If I am, why is this only an issue on macOS, and not all platforms?

@mcuee
Copy link
Collaborator

mcuee commented Aug 4, 2024

@MX682X so the reason for using libusb here is to be able to write to specific endpoints, which hidapi does not support. But the way libusb is implemented in usb_libusb.c, it doesn't work with high-speed USB, but only full-speed. Am I right?

If I am, why is this only an issue on macOS, and not all platforms?

It is not possible (or nearly impossible) to detach kernel hid driver under macOS to use libusb.
https://github.com/libusb/libusb/wiki/FAQ#user-content-Does_libusb_support_USB_HID_devices

The bug with libusb fallback for USB HID device is a different story. I think it does not work for full speed USB device like PICKit 4 and SNAP. I do not have Atmel ICE and Power Debugger to test whether the fallback works for them or not. You may want to test them under Linux or Windows (you can not test under macOS as libusb will not work).

You can refer to the comments by @askn37

Yes, ideally you should put fd->usb.max_xfer = 64; at the beginning of usbhid_open(), but I don't know which known devices this affects, so I'll change the default once I'm sure.

Currently, all USB-HID devices that link at Full-Speed must have max=64 to work, if their "USB Report Descriptor" requests a report size of 64. The only exception I know of is ATMELICE3, which has a report size of 512.

@mcuee
Copy link
Collaborator

mcuee commented Aug 4, 2024

Ok, so MacOS rellay needs usbhid and can't compile with libusb.... this is bad, because from what I know I have to talk to the Specific Endpoints 1 (Read command response), 2 (Command write), 3 (Data channel for memory read) 4 (Data channel for memory write) and I didn't see usbhid offering a way to specify the EP the data is sent to/read from. This is even the reason why I copy-pasted the libusb transfer functions but with different endpoints...

The recommendation is really to use hidapi and not libusb for USB HID device.
https://github.com/libusb/libusb/wiki/FAQ#user-content-Does_libusb_support_USB_HID_devices

As for the translation between libusb and hidapi, I think the USB HID spec is quite useful. You can read CH7 and CH8.
https://www.usb.org/sites/default/files/hid1_11.pdf

Basically hidapi talks in HID report (input, output and feature report). libusb talks by endpoint with different transfer type (only Control Transfer and Interrupt transfer are involved for USB HID device).

That being said, you can continue your work with libusb. If you make it work, that helps a lot already. We can leave macOS to the later.

BTW, PICKit 2 avrdude support does not work under macOS for the same reason -- it uses libusb (or Windows native HID API under Windows). It needs to be ported to hidapi as well in order for macOS support to work.

@mcuee
Copy link
Collaborator

mcuee commented Aug 4, 2024

@MX682X

You can use the following tool to parse the USB HID report descriptors under Linux (Windows is not good at this, macOS is good).
https://github.com/DIGImend/usbhid-dump

Or you can use hidapi's hidtest utility under Linux to dump the raw USB HID report descriptor and then uses online tools to parse. This is the method I used in Issue #1221.
https://eleccelerator.com/usbdescreqparser/

Example HID Report Descriptor dump by @askn37 for Atmel ICE using macOS.
#1221 (comment)

@MX682X
Copy link
Contributor Author

MX682X commented Aug 4, 2024

The files scripts_lut.[ch] should be renamed pickit5_lut.[ch] (we have 53 programmer types with 167 programmers, names are important for us to find our way through the code)

@stefanrueger Thanks for the reminder. The reason why I decided to name it that way at the beginning was that the scripts are not exclusive to the PICkit5, they should work with the PICkit4 (when in PIC mode) as well. So by changing the PID locally on your end to match the PICkit4, the 5 code should run with the 4.

Namespaces: given the collection of many programmers global symbols such as chip_lut can be mildly disorienting for the maintainers. I'd suggest either #include the tables into pickit5.c and make them static or
rename the tables to sth like pickit5_chip_lut if you prefer them compiled separately and linked.

The reason for the different files is that I have written a Python script that grabs the scripts.xml file from a Toolpack, filters the UPDI functions, compresses them through a look-up-table and creates the C and H files necessary for compilation (a config file or something would be probably better, but I have no experience with that topic)

How invested are you in the formatting? It's OK if you are, but if you don't mind, and seeing that it's the initial commit, I'd (slightly) prefer running the code through an indent program with (current) AVRDUDE style

Go Ahead

Is it OK if I push commits onto your branch, eg, smaller things, tricky points for AVRDUDE integration, or formatting?

Fine by me

Do you want (after all is done) a squash merge or one that keeps the individual commits?

I prefer a squash merge, as it is more clean

Oh, and one more question: Can you tell me how I can cross-compile avrdude for Windows/MacOS?

@MX682X
Copy link
Contributor Author

MX682X commented Aug 4, 2024

it doesn't work with high-speed USB, but only full-speed.

@MCUdude I'm not sure, but it worked High-Speed on my end, I think. Transfer Size is 512 bytes. However, I also found out, that the Endpoints are not HID, but Vendor Specific (0xFF), thus usbhid fails to open, I think.

@MX682X
Copy link
Contributor Author

MX682X commented Aug 4, 2024

@mcuee usbhid-dump did not find any HID devices (Ubuntu) with the debugger connected.
Wireshark catched the configuration:

Frame 18440: 176 bytes on wire (1408 bits), 176 bytes captured (1408 bits) on interface usbmon1, id 0
USB URB
CONFIGURATION DESCRIPTOR
    bLength: 9
    bDescriptorType: 0x02 (CONFIGURATION)
    wTotalLength: 112
    bNumInterfaces: 3
    bConfigurationValue: 1
    iConfiguration: 0
    Configuration bmAttributes: 0xc0  SELF-POWERED  NO REMOTE-WAKEUP
        1... .... = Must be 1: Must be 1 for USB 1.1 and higher
        .1.. .... = Self-Powered: This device is SELF-POWERED
        ..0. .... = Remote Wakeup: This device does NOT support remote wakeup
    bMaxPower: 250  (500mA)
INTERFACE DESCRIPTOR (0.0): class Vendor Specific
    bLength: 9
    bDescriptorType: 0x04 (INTERFACE)
    bInterfaceNumber: 0
    bAlternateSetting: 0
    bNumEndpoints: 4
    bInterfaceClass: Vendor Specific (0xff)
    bInterfaceSubClass: 0xff
    bInterfaceProtocol: 0xff
    iInterface: 0
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x81  IN  Endpoint:1
    bmAttributes: 0x02
    wMaxPacketSize: 512
    bInterval: 0
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x02  OUT  Endpoint:2
    bmAttributes: 0x02
    wMaxPacketSize: 512
    bInterval: 0
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x83  IN  Endpoint:3
    bmAttributes: 0x02
    wMaxPacketSize: 512
    bInterval: 0
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x04  OUT  Endpoint:4
    bmAttributes: 0x02
    wMaxPacketSize: 512
    bInterval: 0
INTERFACE ASSOCIATION DESCRIPTOR
    bLength: 8
    bDescriptorType: 0x0b (INTERFACE ASSOCIATION)
    bFirstInterface: 1
    bInterfaceCount: 2
    bFunctionClass: Communications and CDC Control (0x02)
    bFunctionSubClass: 0x02
    bFunctionProtocol: 0x01
    iFunction: 0
INTERFACE DESCRIPTOR (1.0): class Communications and CDC Control
    bLength: 9
    bDescriptorType: 0x04 (INTERFACE)
    bInterfaceNumber: 1
    bAlternateSetting: 0
    bNumEndpoints: 1
    bInterfaceClass: Communications and CDC Control (0x02)
    bInterfaceSubClass: Abstract Control Model (0x02)
    bInterfaceProtocol: AT Commands: V.250 etc (0x01)
    iInterface: 0
COMMUNICATIONS DESCRIPTOR
    bLength: 5
    bDescriptorType: 0x24 (CS_INTERFACE)
    Descriptor Subtype: Header Functional Descriptor (0x00)
    CDC: 0x0110
COMMUNICATIONS DESCRIPTOR
    bLength: 4
    bDescriptorType: 0x24 (CS_INTERFACE)
    Descriptor Subtype: Abstract Control Management Functional Descriptor (0x02)
    bmCapabilities: 0x02
COMMUNICATIONS DESCRIPTOR
    bLength: 5
    bDescriptorType: 0x24 (CS_INTERFACE)
    Descriptor Subtype: Union Functional Descriptor (0x06)
    Control Interface: 0x01
    Subordinate Interface: 0x02
COMMUNICATIONS DESCRIPTOR
    bLength: 5
    bDescriptorType: 0x24 (CS_INTERFACE)
    Descriptor Subtype: Call Management Functional Descriptor (0x01)
    bmCapabilities: 0x03
    Data Interface: 0x02
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x85  IN  Endpoint:5
    bmAttributes: 0x03
    wMaxPacketSize: 64
    bInterval: 16
INTERFACE DESCRIPTOR (2.0): class CDC-Data
    bLength: 9
    bDescriptorType: 0x04 (INTERFACE)
    bInterfaceNumber: 2
    bAlternateSetting: 0
    bNumEndpoints: 2
    bInterfaceClass: CDC-Data (0x0a)
    bInterfaceSubClass: 0x00
    bInterfaceProtocol: No class specific protocol required (0x00)
    iInterface: 0
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x86  IN  Endpoint:6
    bmAttributes: 0x02
    wMaxPacketSize: 64
    bInterval: 0
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x07  OUT  Endpoint:7
    bmAttributes: 0x02
    wMaxPacketSize: 64
    bInterval: 0

Also, avrdude reports the following on init:

Avrdude version 7.3-20240803 (3079b439)
Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

System wide configuration file is /home/user/avrdude/build_linux/src/avrdude.conf
User configuration file /root/.avrduderc does not exist

Using port            : usb
Using programmer      : pickit5
Programmer baud rate  : 200000
Pickit5_open("usb")
USB device with VID: 0x04d8 and PID: 0x9036 not found
Usbdev_open(): found MPLAB� PICkit 5, serno: ***
Warning usbdev_open() [usb_libusb.c:189]: unable to set configuration 1: could not set config 1: Device or resource busy
AVR part              : AVR32DD28
Programming modes     : SPM, UPDI

lsusb says it is connected, though:

Bus 001 Device 012: ID 04d8:9036 Microchip Technology, Inc. MPLAB® PICkit 5

@MCUdude
Copy link
Collaborator

MCUdude commented Aug 4, 2024

The reason why I decided to name it that way at the beginning was that the scripts are not exclusive to the PICkit5, they should work with the PICkit4 (when in PIC mode) as well. So by changing the PID locally on your end to match the PICkit4, the 5 code should run with the 4.

That's good to know. According to a Microchip developer, this PR should also work with the ICE4 and ICD5 programmers as well. And if it works with PICkit4 in PIC mode, it works with the MPLAB SNAP in PIC mode as well.

@MX682X I do have a PICkit4 I can use with MPLAB X to get some Wireshark data on my Mac, if that's useful to you.
Just tell me what you want me to do (flash a part, etc.) and I'll see what I can do.

@MX682X
Copy link
Contributor Author

MX682X commented Aug 4, 2024

The reason why I decided to name it that way at the beginning was that the scripts are not exclusive to the PICkit5, they should work with the PICkit4 (when in PIC mode) as well. So by changing the PID locally on your end to match the PICkit4, the 5 code should run with the 4.

That's good to know. According to a Microchip developer, this PR should also work with the ICE4 and ICD5 programmers as well. And if it works with PICkit4 in PIC mode, it works with the MPLAB SNAP in PIC mode as well.

@MX682X I do have a PICkit4 I can use with MPLAB X to get some Wireshark data on my Mac, if that's useful to you. Just tell me what you want me to do (flash a part, etc.) and I'll see what I can do.

Preferably one capture on Readout of Program (empty chip is fine) and one Upload of a small Program, preferably < 1023 bytes

@MCUdude
Copy link
Collaborator

MCUdude commented Aug 4, 2024

I'll see what I can do. Is it OK if I email you the capture files?

@MX682X
Copy link
Contributor Author

MX682X commented Aug 4, 2024

I'd prefer a zip attached to a comment, but I guess you can send it to *************** (without spaces)
but just a headsup: I'm only checking that mailbox if I expect an email

EDIT by MCUdude: removed email address

@MCUdude
Copy link
Collaborator

MCUdude commented Aug 4, 2024

@MX682X email sent!

@MX682X
Copy link
Contributor Author

MX682X commented Aug 4, 2024

Yes, thanks. What I can say, is that the payloads are identical, so pickit 4 in PIC mode should be supportable.
There are also High-Speed Transfers with 4 Endpoints still, no HID packets, only Vendor Specific (0xFF).
This means, that I will throw out my attempt of usbhid support alltogether, as the PICkits don't talk in HID at all.

Looking further into the matter, I think the build Problem lies in bad #if defines #include at the top of the file

@askn37
Copy link
Contributor

askn37 commented Aug 12, 2024

I personally reckon that Microchip has created a security issue by moving the signature address to a different place,

I made the same guess when AVR-EB was announced.

Another reason is that USERROW and BOOTROW in AVR-Dx/Ex families are FLASH memory characteristics, not EEPROM, and therefore need to support page erase commands. They need to be pages in one block, so the base address needs to be a clean paragraph, otherwise it will clutter the on-die address calculation circuitry. It seems they also wanted to standardize the EEPROM base address across the family to 0x1400. Next to that is where the microcode for UPDI, OCD, etc. is stored, and they didn't want to cut that out and extend it, so 0x1100 was sacrificed.

@MX682X
Copy link
Contributor Author

MX682X commented Aug 12, 2024

decided against it mainly owing to a belief that would increase maintenance (we don't know how future Microchip chips will use sib and where they would place the device ID).

The mentioned fix calculates the offset at runtime, while I'm using "hard-coded" instructions with the scripts. I just have some if conditions that check the allowed range from 0 to 3 and 4 to 9, and decide on that which script pointer to return. And as a fallback version, there is still the look up by name.

it's always failing on my avr32dd28, even though the commands run successfully, thus I can't look into it on my end

@MX682X the test-avrdude script will declare a run as failed if there is output from avrdude on stdout or stderr on using -qq. This can happen when there is a debug output. Remove all debug output before using this script.

I see, this helps.

Here is the testrun summary
   ./test-avrdude -e ../build_linux/src/avrdude -d1 -p "-c pickit5_updi -p avr32dd28 -b900000"
Testing ../build_linux/src/avrdudePrepare "-c pickit5_updi -p avr32dd28 -b900000" and press 'enter' or 'space' to continue. Press any other key to skip
   2,005 s: fuse access: clear, set and read eesave fuse bit (failed command below)
$ ../build_linux/src/avrdude -qq -c pickit5_updi -p avr32dd28 -b900000 -T "config eesave=0; config eesave=1; config eesave"
   1,764 s: fuse access: set eesave fusebit to delete EEPROM on chip erase (failed command below)
$ ../build_linux/src/avrdude -qq -c pickit5_updi -p avr32dd28 -b900000 -T "config eesave=ee*erased"
   2,723 s: chip erase
   3,310 s: flash -U write/verify holes_rjmp_loops_32768B.hex
   1,870 s: flash -T write/verify holes_rjmp_loops_32768B.hex (failed command below)
$ ../build_linux/src/avrdude -qq -c pickit5_updi -p avr32dd28 -b900000 -T "write flash ./test_files/holes_rjmp_loops_32768B.hex:a"
   3,237 s: flash -T write/verify rjmp_loops_for_bootloaders_32768B.hex (failed command below)
$ ../build_linux/src/avrdude -qq -c pickit5_updi -p avr32dd28 -b900000 -T "write flash ./test_files/rjmp_loops_for_bootloaders_32768B.hex:a"
   2,630 s: eeprom check whether programmer can flip 0s to 1s
   2,607 s: eeprom -U write/verify holes_pack_my_box_256B.hex
   3,694 s: eeprom -T write/verify holes_{the_five_boxing_wizards,pack_my_box}_256B.hex (failed command below)
$ ../build_linux/src/avrdude -qq -c pickit5_updi -p avr32dd28 -b900000 -T "write eeprom ./test_files/holes_the_five_boxing_wizards_256B.hex:a" -T flush -T "write eeprom ./test_files/holes_pack_my_box_256B.hex:a"
   5,637 s: eeprom -T write/verify lorem_ipsum_256B.srec (failed command below)
$ ../build_linux/src/avrdude -qq -c pickit5_updi -p avr32dd28 -b900000 -T "write eeprom ./test_files/lorem_ipsum_256B.srec:a"
   2,793 s: chip erase and spot check flash is actually erased
   1,650 s: spot check eeprom is erased, too
   1,643 s: usersig -T/-U write/read random_data_32B.bin (failed command below)
$ ../build_linux/src/avrdude -qq -c pickit5_updi -p avr32dd28 -b900000 -T "erase usersig; write usersig ./test_files/random_data_32B.bin" -T flush -U usersig:r:/dev/shm/test-avrdude.tmp.MsuY4u:r -U usersig:v:/dev/shm/test-avrdude.tmp.MsuY4u:r -T "erase usersig" -T flush -U usersig:v:./test_files/0xff_32B.hex:i

The first fail returns this:


../build_linux/src/avrdude -qq -c pickit5_updi -p avr32dd28 -b900000 -T "config eesave=0; config eesave=1; config eesave"
Warning: unable to set configuration 1: could not set config 1: Device or resource busy
config eesave=eex_preserved # 1

All others have just the warning. I haven't thought much about it as it seems to work and thought it might be just on my end. With -vvvv I get Warning usbdev_open() [usb_libusb.c:189]: unable to set configuration 1: could not set config 1: Device or resource busy I guess this might make it fail? Could be the source of @mcuu 's test fails aswell... Does anyone know what it is about and how to avoid the error? I'm on Ubuntu 24.04, if that helps.

@stefanrueger
Copy link
Collaborator

@MX682X Great, thanks for sharing results and finding the source of the warning in usb_libusb.c. OK, we have to solve this.

Best would be to figure out how to avoid the set configuration 1 error (and avoid it). If pickit5 cannot avoid that warning and if it is of no consequence, we could downgrade the warning from pmsg_warning() to pmsg_notice(). (If that's the outcome, then before downgrading the warning message please merge git main into your branch, @MX682X; otherwise you get merge conflicts)

@stefanrueger
Copy link
Collaborator

BTW, the logic of test-avrdude is that tests with -T terminal commands don't set avrdude's exit value on error; in order to catch these the proxy is that if an error or a warning is issued (stderr output is non-empty) an avrdude run is deemed faulty. test-avrdude tests only involving -U commands just use the exit value of avrdude to determine whether it went OK.

And the logic of not wanting warnings in -c programmers is that they are only helpful if the user can do something about them or if they help explain a problem further down the line. Anything else the warning shouldn't be there.

@MX682X
Copy link
Contributor Author

MX682X commented Aug 12, 2024

As a quick solution I locally changed the warning in usb_libusb.c to notice, and the test completed successfully

Tested AVR32DD28 and Attiny1614
./test-avrdude -e ../build_linux/src/avrdude -d1 -p "-c pickit5_updi -p avr32dd28 -b900000"
Testing ../build_linux/src/avrdudePrepare "-c pickit5_updi -p avr32dd28 -b900000" and press 'enter' or 'space' to continue. Press any other key to skip
   1,644 s: fuse access: clear, set and read eesave fuse bit
   1,611 s: fuse access: set eesave fusebit to delete EEPROM on chip erase
   2,726 s: chip erase
   3,215 s: flash -U write/verify holes_rjmp_loops_32768B.hex
   1,713 s: flash -T write/verify holes_rjmp_loops_32768B.hex
   2,603 s: eeprom check whether programmer can flip 0s to 1s
   2,668 s: eeprom -U write/verify holes_pack_my_box_256B.hex
   3,727 s: eeprom -T write/verify holes_{the_five_boxing_wizards,pack_my_box}_256B.hex
   2,829 s: chip erase and spot check flash is actually erased
   1,742 s: spot check eeprom is erased, too
   1,645 s: usersig -T/-U write/read random_data_32B.bin



./test-avrdude -e ../build_linux/src/avrdude -d1 -p "-c pickit5_updi -pt1614 -b900000"
Testing ../build_linux/src/avrdudePrepare "-c pickit5_updi -pt1614 -b900000" and press 'enter' or 'space' to continue. Press any other key to skip
   1,617 s: fuse access: clear, set and read eesave fuse bit
   1,708 s: fuse access: set eesave fusebit to delete EEPROM on chip erase
   2,856 s: chip erase
   3,632 s: flash -U write/verify holes_rjmp_loops_16384B.hex
   1,870 s: flash -T write/verify holes_rjmp_loops_16384B.hex
   1,645 s: eeprom check whether programmer can flip 0s to 1s
   1,872 s: eeprom -U write/verify holes_pack_my_box_256B.hex
   1,710 s: eeprom -T write/verify holes_{the_five_boxing_wizards,pack_my_box}_256B.hex
   3,118 s: chip erase and spot check flash is actually erased
   1,613 s: spot check eeprom is erased, too
   1,644 s: usersig -T/-U write/read random_data_32B.bin

@stefanrueger
Copy link
Collaborator

@MX682X Looks like we are converging? Likely to review tonight and push commits with small changes onto this PR. Let me know if I should wait

@stefanrueger
Copy link
Collaborator

@MX682X I have done some minor formatting etc.

Most looks good:

  • I like the symbolic vid/pid names; it is better though, if that kind of thing was done generally for all usb programmers (in a different PR I hasten to add); otherwise it's difficult to document, difficult for users to remember (which -c programmer allows the -P option to be symbolic, and what were the symbols again); it is probably better for everyone involved if that feature was built back for now
  • I saw a todo comment that I took as a future extension to change the BOD fuse? I would discourage that as it's a user decision (and I deleted the comment)
  • Would be fab to have the -x options in avrdude.1 and doc/avrdude.texi documented (all programmers with -x options have that)
  • Tiny thingy: last three lines of the _lut.c file have two spaces indentation too many: probably needs the .py source changing

I might have another look in a couple of days, but so far, I'm very pleased with this new -c programmer

@MX682X
Copy link
Contributor Author

MX682X commented Aug 13, 2024

@MX682X I have done some minor formatting etc.

Most looks good:

I like the symbolic vid/pid names; it is better though, if that kind of thing was done generally for all usb programmers (in a different PR I hasten to add); otherwise it's difficult to document, difficult for users to remember (which -c programmer allows the -P option to be symbolic, and what were the symbols again); it is probably better for everyone involved if that feature was built back for now

I already had the thought, that it might be pretty useless, if not documented properly, and I agree, it would make more sense to do it globally, especially as it would allow to improve the -v output. But then again, what harm would it be to have the feature available there for now?

I saw a todo comment that I took as a future extension to change the BOD fuse? I would discourage that as it's a user decision (and I deleted the comment)

The datasheet says, that it is recommended to change the BOD setting to the highest value, so no need to change fuses, setting the register directly would be enough. However, MPLAB isn't following the datasheet either, so I guess it should be fine to keep it like that.

Would be fab to have the -x options in avrdude.1 and doc/avrdude.texi documented (all programmers with -x options have that)

I managed to do .texi, but the avrdude.1 has some weird syntax. Would be better if somone with more experience would do that part. Also: How do I "compile" the docs? Haven't seen any doc files.

Tiny thingy: last three lines of the _lut.c file have two spaces indentation too many: probably needs the .py source changing

Done

While doing the .texi, I noticed that the SNAP doesn't support HV and can't provide power, so I added some checks for that, just to make sure. Couldn't add the checks in extended params already, as we only find out the device we're connected with later in open()

@MX682X
Copy link
Contributor Author

MX682X commented Aug 13, 2024

Also, I wonder, if it's possible to overwrite the functions associated with a programmer to use the functions of another programmer during runtime.
Like, when the user said -c pickit4_updiand the PK4 is in PIC mode, then call pickit5_initpgm() to overwrite the existing pgm functions. Or is the whole thing too error prone?

EDIT: What I want to say is, that it will end up being pretty confusing specifing pickit 5 to talk to pickit 4. It would be significantly better, user-interface wise, not to clobber them together. I did expect the scripts to be backwards compatible, but not that well. Maybe the PIC mode support could be designated experimental, impling that it will be changed in the future?

@MCUdude
Copy link
Collaborator

MCUdude commented Aug 13, 2024

I managed to do .texi, but the avrdude.1 has some weird syntax. Would be better if somone with more experience would do that part. Also: How do I "compile" the docs? Haven't seen any doc files.

I run $ nroff -man avrdude.1 | less to view the man docs. I haven't created texi PDFs yet, but I'm able to preview it in VSCode using the Latex Workshop plugin + installing texi2html and texinfo using your favorite package manager.

@stefanrueger
Copy link
Collaborator

what harm would it be to have the feature available there for now?

It sets expectations and either binds future contributors to the strings used here or risks breaking something that users might have started relying on in scripts etc. For example, a global solution might not use mc and at but instead the full names potentially abbreviated to the smallest unique string (m, mi, mic, ... but not mc). That wouldn't be compatible.

setting the [BOD] register directly

Ahh, got you. AVRDUDE knows where these registers are. Do you need bod.ctrla? libavrdude has functions on how to get at the required address, eg, something along the lines

  int nr = 0;
  const Register_file *boda, *rf = avr_locate_register_file(part, &nr);
  if(rf && (boda = avr_locate_register(rf, nr, "bod.ctrla", str_eq))) {
    // boda now points to register info incl address of bod.ctrla
  }

should enable you to do what you want.

overwrite the functions associated with a programmer to use the functions of another programmer during runtime

Can be done, and has been done. It's a nightmare for maintenance, though. And I absolutely discourage that. Much better to tell the user of a PK4 in PIC mode they can either switch it to AVR mode and continue to use -c pickit4_xyz or use -c pickit5_xyz.

@stefanrueger
Copy link
Collaborator

@MX682X I have decided it is better at this point to not commit to specific pid/vid aliases in the -c pickit5 programmer. I very much do like the idea, but it's better to think about how this works on an AVRDUDE level rather than programmer level. A PR (after v8.0 release) would be vvv welcome.

Here how the LaTex docu looks like. There is a slight problem that SNAP appears three times and that the third time the options don't seem to pertain to SNAP (or do they?). @MX682X what is correct?

@MCUdude Should we do something about a single physical programmer having multiple entries here? Unrelated to this PR: Should this section not be about -c programmer options rather than physical programmers? The problem is that a physical programmer (eg, PICKit 4) can have multiple -c programmers serving it which may have different options. I have an ever so slight preference for listing the options according to -c programmers but leave it to you @MCUdude to lead on this.

pickit

@MX682X
Copy link
Contributor Author

MX682X commented Aug 14, 2024

I have decided it is better at this point to not commit to specific pid/vid aliases in the -c pickit5 programmer.

I was just about to do a commit, when I saw your pushes. Removed some lingering function calls that were useless at this point.

Here how the LaTex docu looks like. There is a slight problem that SNAP appears three times and that the third time the options don't seem to pertain to SNAP (or do they?). @MX682X what is correct?

When I copy pasted the paragraph above, I did not know that SNAP has no voltage converter at all, and it kinda persisted. So the last "SNAP" should be replaced with "PICkit 4", I guess

@stefanrueger
Copy link
Collaborator

stefanrueger commented Aug 14, 2024

OK, this is now almost ready to merge

  • The last "SNAP" should be replaced with "PICkit 4" [edit: done]
  • We still need avrdude.1 docu (though that can come after the merge)
  • Happy to wait for BOD register change if you want to do that @MX682X (no problem if not)

Unless I hear otherwise I will squash merge (I think that was @MX682X's preference). We normally credit contributors of substantial pieces of work in AUTHORS, typically real name and optional email address. @MX682X how do you want to appear there? Aliases or usernames should be OK if that's what your pref is.

@MX682X
Copy link
Contributor Author

MX682X commented Aug 14, 2024

Happy to wait for BOD register change if you want to do that @MX682X (no problem if not)

Forgot to mention: I thought about it and I think it will be kinda annoying to implement. There are a couple of script functions that activate UPDI System Reset, meaning that the BOD Register will be reset after it, so I think it might be better to go without this. MPLAB isn't doing it either, and we have one voltage measurement anyway.

Aliases or usernames should be OK if that's what your pref is.

I'd rather prefer my alias.

@stefanrueger stefanrueger merged commit beaebd9 into avrdudes:main Aug 14, 2024
13 checks passed
@MX682X
Copy link
Contributor Author

MX682X commented Aug 14, 2024

I'm not sure if it matters, but I'd like to point out that I haven't committed the workaround in usb_libusb.c (pmsg_warning to pmsg_notice), the line that gave the config warnings and made test-avrdude fail.

@stefanrueger
Copy link
Collaborator

@MX682X Thanks! Done now

@stefanrueger
Copy link
Collaborator

stefanrueger commented Aug 14, 2024

Actually the better approach would be to find a way not to get the warning (perhaps not configuring if already configured)... [edit On the other hand now is not the time to tinker with central code]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants