avrdudes / avrdude

AVRDUDE is a utility to program AVR microcontrollers
GNU General Public License v2.0
734 stars 136 forks source link

linuxgpio cannot use pin 0 #1228

Closed wijnen closed 1 year ago

wijnen commented 1 year ago

Most devices with gpio pins start counting from 0. However, when defining a linuxgpio programmer to use e.g. reset=0, it fails with the message "avrdude: error: no pin has been assigned for AVR RESET". Apparently a value of 0 counts as "undefined".

Because of this, it is impossible to use pin 0, even though it is a perfectly valid pin to use.

I'm not sure if there needs to be a way to specify "undefined" for a pin, but if there is, it should be something that cannot be a real pin, such as the word "undefined", or a negative value.

For reference, here's a sample avrdude.conf file:

programmer
  id    = "opi";
  desc  = "Program using OrangePi Zero GPIO pins";
  type  = "linuxgpio";
  reset = 0;
  sck   = 11;
  mosi  = 12;
  miso  = 6;
;

I use it with "sudo avrdude -C +avrdude.conf -c opi -p attiny24 -U hfuse:r:-:h"

MCUdude commented 1 year ago

Hi @wijnen, and thanks for reporting!

This check is what's causing the error:

https://github.com/avrdudes/avrdude/blob/159d12693e8787fab5bf68d87f331bedf85164a1/src/bitbang.c#L611-L617

Can you try to modify the source code (for instance, replace the code with the code below) just to check if using GPIO 0 will actually work?

static int verify_pin_assigned(const PROGRAMMER *pgm, int pin, char *desc) {
  return 0;
}
wijnen commented 1 year ago

To do it right, the value 0 should be valid and not mean "unused". I've written a patch (for the Debian stable version, so it doesn't exactly apply to the code here, but that should be easy to fix).

If I have time, I'll turn it into a pull request. But if it gets merged before I get around to it, that's even better. :-)

Here is the patch file.

The system I use it on is too weak to compile avrdude on, so I couldn't test it there. I did however test it on my regular PC and it works as I would expect. That means:

So I'm pretty confident that this will work. If you have no way of testing it on hardware, I can do it, but it's a lot of work which I'd rather avoid.

mcuee commented 1 year ago

@wijnen PR will be most welcome. You can carry out the test on your OrangePi Zero target later. I have a few OrangePi boards and I will see if I can get Linux GPIO work on one of them.

wijnen commented 1 year ago

I made the PR. I haven't had time to test it at all yet and I'm not sure when I will, so I thought I'd just send it now. Please check and test it before merging.

wijnen commented 1 year ago

I saw a comment that asked for a #define NO_PIN -1. That seemed like a good idea, so I did that. Now it says there is a review that requests a change, but I can't see the review, or the requested change. I did a commit --amend and a push --force, so perhaps that caused some things to get lost.

If there is still a request for a change, please let me know what that is (and where I could have found it).

Anyway, what seems weird to me is the pin mask. The code expects pins to be able to be masked out of the pin number with a binary and operation, it seems. I'm guessing this would work for other systems, but it will certainly not work for linuxgpio. So while the change (from (pinno & mask) == 0 to pinno == NO_PIN) makes no difference for linuxgpio, I'm not sure if I'm breaking anything for other targets.

mcuee commented 1 year ago

@wijnen

@stefanrueger has updated your PR. Please review as well. Thanks.

mcuee commented 1 year ago

I need to find out how to use GPIO_0 under Raspberry Pi, it seems to be reserved (no GPIO_0/GPIO_1). https://projects.raspberrypi.org/en/projects/physical-computing/1

Edit -- the following helps me to use GPIO_0. https://raspberrypi.stackexchange.com/questions/111312/more-information-about-gpio0-and-gpio1 GPIO_0 is ID_SD GPIO_1 is ID_SC

According to the official docs you can switch off their usage in /boot/config.txt. Just set force_eeprom_read to 0. force_eeprom_read=0 Taken from: https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md force_eeprom_read Set this option to 0 to prevent the firmware from trying to read an I2C HAT EEPROM (connected to pins ID_SD & ID_SC) at powerup.

mcuee commented 1 year ago

Using GPIO_25 as RESET Pin:

pi@raspberrypi:~/Desktop/build/avr/avrdude_bin $ ./avrdude -c linuxgpio -P GPIO -p m328p -v -U flash:r:m328p_read.hex:i

avrdude: Version 7.0-20221223 (8573442)
         Copyright the AVRDUDE authors;
         see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

         System wide configuration file is /home/pi/Desktop/build/avr/avrdude_bin/avrdude.conf
         User configuration file is /home/pi/.avrduderc
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : GPIO
         Using Programmer              : linuxgpio
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : possible i/o
         RETRY pulse                   : SCK
         Serial program mode           : yes
         Parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                           Block Poll               Page                       Polled
           Memory Type Alias    Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom                 65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash                  65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
           hfuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
           efuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
           lock                    0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
           signature               0     0     0    0 no          3    1      0     0     0 0x00 0x00
           calibration             0     0     0    0 no          1    1      0     0     0 0x00 0x00

         Programmer Type : linuxgpio
         Description     : Use the Linux sysfs interface to bitbang GPIO lines
         Pin assignment  : /sys/class/gpio/gpio{n}
           RESET   =  25
           SCK     =  11
           SDO     =  10
           SDI     =  9

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e950f (probably m328p)
avrdude: reading flash memory ...

Reading | ################################################## | 100% 6.48 s 

avrdude: writing output file m328p_read.hex

avrdude done.  Thank you.

Using GPIO_0 as RESET.

pi@raspberrypi:~/Desktop/build/avr/avrdude_bin $ ./avrdude -c linuxgpio -P GPIO -p m328p -v -U flash:r:m328p_read.hex:i

avrdude: Version 7.0-20221223 (8573442)
         Copyright the AVRDUDE authors;
         see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

         System wide configuration file is /home/pi/Desktop/build/avr/avrdude_bin/avrdude.conf
         User configuration file is /home/pi/.avrduderc
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : GPIO
         Using Programmer              : linuxgpio
avrdude verify_pin_assigned() error: no pin has been assigned for AVR RESET
avrdude main() error: unable to open programmer linuxgpio on port GPIO

avrdude done.  Thank you.
mcuee commented 1 year ago

PR #1231 is good.

But I think it is too verbose with -v.

pi@raspberrypi:~/Desktop/build/avr/avrdude_bin $ ./avrdude_pr1231 -c linuxgpio -p m328p -v

avrdude_pr1231: Version 7.0-20221223 (184c62c)
                Copyright the AVRDUDE authors;
                see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

                System wide configuration file is /home/pi/Desktop/build/avr/avrdude_bin/avrdude.conf
                User configuration file is /home/pi/.avrduderc
                User configuration file does not exist or is not a regular file, skipping

                Using Port                    : /dev/parport0
                Using Programmer              : linuxgpio
                AVR Part                      : ATmega328P
                Chip Erase delay              : 9000 us
                PAGEL                         : PD7
                BS2                           : PC2
                RESET disposition             : possible i/o
                RETRY pulse                   : SCK
                Serial program mode           : yes
                Parallel program mode         : yes
                Timeout                       : 200
                StabDelay                     : 100
                CmdexeDelay                   : 25
                SyncLoops                     : 32
                PollIndex                     : 3
                PollValue                     : 0x53
                Memory Detail                 :

                                                  Block Poll               Page                       Polled
                  Memory Type Alias    Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
                  ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
                  eeprom                 65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
                  flash                  65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
                  lfuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
                  hfuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
                  efuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
                  lock                    0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
                  signature               0     0     0    0 no          3    1      0     0     0 0x00 0x00
                  calibration             0     0     0    0 no          1    1      0     0     0 0x00 0x00

                Programmer Type : linuxgpio
                Description     : Use the Linux sysfs interface to bitbang GPIO lines
                Pin assignment  : /sys/class/gpio/gpio{n}
                  RESET   =  0
                  SCK     =  11
                  SDO     =  10
                  SDI     =  9

11110avrdude_pr1231: AVR device initialized and ready to accept instructions
011011011avrdude_pr1231: device signature = 0x1e950f (probably m328p)
1
avrdude_pr1231 done.  Thank you.

pi@raspberrypi:~/Desktop/build/avr/avrdude_bin $ ./avrdude_pr1231 -c linuxgpio -P GPIO -p m328p -v -U flash:r:m328p_read_pr1231.hex:i

avrdude_pr1231: Version 7.0-20221223 (184c62c)
                Copyright the AVRDUDE authors;
                see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

                System wide configuration file is /home/pi/Desktop/build/avr/avrdude_bin/avrdude.conf
                User configuration file is /home/pi/.avrduderc
                User configuration file does not exist or is not a regular file, skipping

                Using Port                    : GPIO
                Using Programmer              : linuxgpio
                AVR Part                      : ATmega328P
                Chip Erase delay              : 9000 us
                PAGEL                         : PD7
                BS2                           : PC2
                RESET disposition             : possible i/o
                RETRY pulse                   : SCK
                Serial program mode           : yes
                Parallel program mode         : yes
                Timeout                       : 200
                StabDelay                     : 100
                CmdexeDelay                   : 25
                SyncLoops                     : 32
                PollIndex                     : 3
                PollValue                     : 0x53
                Memory Detail                 :

                                                  Block Poll               Page                       Polled
                  Memory Type Alias    Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
                  ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
                  eeprom                 65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
                  flash                  65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
                  lfuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
                  hfuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
                  efuse                   0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
                  lock                    0     0     0    0 no          1    1      0  4500  4500 0x00 0x00
                  signature               0     0     0    0 no          3    1      0     0     0 0x00 0x00
                  calibration             0     0     0    0 no          1    1      0     0     0 0x00 0x00

                Programmer Type : linuxgpio
                Description     : Use the Linux sysfs interface to bitbang GPIO lines
                Pin assignment  : /sys/class/gpio/gpio{n}
                  RESET   =  0
                  SCK     =  11
                  SDO     =  10
                  SDI     =  9

11110avrdude_pr1231: AVR device initialized and ready to accept instructions
011011011avrdude_pr1231: device signature = 0x1e950f (probably m328p)
avrdude_pr1231: reading flash memory ...

Reading |                                                    | 0% 0.00 s 01101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101
Reading | #                                                  | 1% 0.09 s 01101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101101
...
...
Reading | ################################################## | 100% 8.25 s 

avrdude_pr1231: writing output file m328p_read_pr1231.hex
1
avrdude_pr1231 done.  Thank you.
mcuee commented 1 year ago

Hmm, I think this is related to GPIO_0 being a special pin for Raspberry Pi (I am testing with Raspberry Pi 3B+). And it has nothing to do with the PR.

I have tried without -v and even -qq, it still prints out those binary streams.

Edit: 1) No, no idea why it becomes so verbose, I used back GPIO_25 and it is the same. 2) Even if I revert back the changes to config.txt, it still does this. Strange.

In any case, PR #1231 is fine.

stefanrueger commented 1 year ago

I have tried without -v and even -qq, it still prints out those binary streams.

The PR certainly does not interfere with messaging. Have you ensured you rebuilt avrdude from scratch? Not doing so is a common cause for tests that go wrong.

mcuee commented 1 year ago

I have tried without -v and even -qq, it still prints out those binary streams.

The PR certainly does not interfere with messaging. Have you ensured you rebuilt avrdude from scratch? Not doing so is a common cause for tests that go wrong.

Yes I have done that. I believe it has something to do with the change to config.txt even though I have reverted it and reboot.

In any case, as you mentioned, it is not related to PR #1231 and it is good to merge PR #1231 now.

mcuee commented 1 year ago

I have also tested -c linuxspi and confirmed it is not affected by this issue. PR #1231 is still good so there is no regression.

BTW, if you want want to use linuxspi or linuxgpio, please take note that there is a bug in git main.

Work-around for #1107, please do not use ON but rather 1 to enable linuxspi and linuxgpio.

pi@raspberrypi:~/Desktop/build/avr/avrdude_git $ cmake -D CMAKE_BUILD_TYPE=RelWithDebInfo
 -D HAVE_LINUXGPIO=1 -D HAVE_LINUXSPI=1 -B build_linux
-- The C compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found Git: /usr/bin/git (found version "2.20.1") 
-- Found FLEX: /usr/bin/flex (found version "2.6.4") 
-- Found BISON: /usr/bin/bison (found version "3.3.2")
-- Looking for libelf.h
-- Looking for libelf.h - found
-- Looking for libelf/libelf.h
-- Looking for libelf/libelf.h - not found
-- Looking for usb.h
-- Looking for usb.h - found
-- Looking for lusb0_usb.h
-- Looking for lusb0_usb.h - not found
-- Looking for libusb.h
-- Looking for libusb.h - not found
-- Looking for libusb-1.0/libusb.h
-- Looking for libusb-1.0/libusb.h - found
-- Looking for hidapi/hidapi.h
-- Looking for hidapi/hidapi.h - found
-- Looking for ftdi_tcioflush
-- Looking for ftdi_tcioflush - found
-- Configuration summary:
-- ----------------------
-- DO HAVE    libelf
-- DO HAVE    libusb
-- DO HAVE    libusb_1_0
-- DO HAVE    libhidapi
-- DON'T HAVE libftdi
-- DO HAVE    libftdi1
-- DO HAVE    libreadline
-- DISABLED   doc
-- DISABLED   parport
-- ENABLED    linuxgpio
-- ENABLED    linuxspi
-- ----------------------
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/Desktop/build/avr/avrdude_git/build_linux

pi@raspberrypi:~/Desktop/build/avr/avrdude_git $ cmake --build build_linux
[  1%] [BISON][Parser] Building parser with bison 3.3.2
[  3%] [FLEX][Parser] Building scanner with flex 2.6.4
Scanning dependencies of target libavrdude
[  4%] Building C object src/CMakeFiles/libavrdude.dir/arduino.c.o
[  6%] Building C object src/CMakeFiles/libavrdude.dir/avr.c.o
[  7%] Building C object src/CMakeFiles/libavrdude.dir/avr910.c.o
[  9%] Building C object src/CMakeFiles/libavrdude.dir/avrcache.c.o
[ 10%] Building C object src/CMakeFiles/libavrdude.dir/avrftdi.c.o
[ 12%] Building C object src/CMakeFiles/libavrdude.dir/avrftdi_tpi.c.o
[ 13%] Building C object src/CMakeFiles/libavrdude.dir/avrpart.c.o
[ 15%] Building C object src/CMakeFiles/libavrdude.dir/bitbang.c.o
[ 16%] Building C object src/CMakeFiles/libavrdude.dir/buspirate.c.o
[ 18%] Building C object src/CMakeFiles/libavrdude.dir/butterfly.c.o
[ 19%] Building C object src/CMakeFiles/libavrdude.dir/config.c.o
[ 21%] Building C object src/CMakeFiles/libavrdude.dir/confwin.c.o
[ 22%] Building C object src/CMakeFiles/libavrdude.dir/crc16.c.o
[ 24%] Building C object src/CMakeFiles/libavrdude.dir/dfu.c.o
[ 25%] Building C object src/CMakeFiles/libavrdude.dir/fileio.c.o
[ 27%] Building C object src/CMakeFiles/libavrdude.dir/flip1.c.o
[ 28%] Building C object src/CMakeFiles/libavrdude.dir/flip2.c.o
[ 30%] Building C object src/CMakeFiles/libavrdude.dir/ft245r.c.o
[ 31%] Building C object src/CMakeFiles/libavrdude.dir/jtagmkI.c.o
[ 33%] Building C object src/CMakeFiles/libavrdude.dir/jtagmkII.c.o
[ 34%] Building C object src/CMakeFiles/libavrdude.dir/jtag3.c.o
[ 36%] Building C object src/CMakeFiles/libavrdude.dir/linuxgpio.c.o
[ 37%] Building C object src/CMakeFiles/libavrdude.dir/linuxspi.c.o
[ 39%] Building C object src/CMakeFiles/libavrdude.dir/lists.c.o
[ 40%] Building C object src/CMakeFiles/libavrdude.dir/micronucleus.c.o
[ 42%] Building C object src/CMakeFiles/libavrdude.dir/par.c.o
[ 43%] Building C object src/CMakeFiles/libavrdude.dir/pgm.c.o
[ 45%] Building C object src/CMakeFiles/libavrdude.dir/pgm_type.c.o
[ 46%] Building C object src/CMakeFiles/libavrdude.dir/pickit2.c.o
[ 48%] Building C object src/CMakeFiles/libavrdude.dir/pindefs.c.o
[ 50%] Building C object src/CMakeFiles/libavrdude.dir/ppi.c.o
[ 51%] Building C object src/CMakeFiles/libavrdude.dir/ppiwin.c.o
[ 53%] Building C object src/CMakeFiles/libavrdude.dir/serbb_posix.c.o
[ 54%] Building C object src/CMakeFiles/libavrdude.dir/serbb_win32.c.o
[ 56%] Building C object src/CMakeFiles/libavrdude.dir/ser_avrdoper.c.o
[ 57%] Building C object src/CMakeFiles/libavrdude.dir/ser_posix.c.o
[ 59%] Building C object src/CMakeFiles/libavrdude.dir/ser_win32.c.o
[ 60%] Building C object src/CMakeFiles/libavrdude.dir/serialupdi.c.o
[ 62%] Building C object src/CMakeFiles/libavrdude.dir/stk500.c.o
[ 63%] Building C object src/CMakeFiles/libavrdude.dir/stk500v2.c.o
[ 65%] Building C object src/CMakeFiles/libavrdude.dir/stk500generic.c.o
[ 66%] Building C object src/CMakeFiles/libavrdude.dir/teensy.c.o
[ 68%] Building C object src/CMakeFiles/libavrdude.dir/updi_link.c.o
[ 69%] Building C object src/CMakeFiles/libavrdude.dir/updi_nvm.c.o
[ 71%] Building C object src/CMakeFiles/libavrdude.dir/updi_readwrite.c.o
[ 72%] Building C object src/CMakeFiles/libavrdude.dir/updi_state.c.o
[ 74%] Building C object src/CMakeFiles/libavrdude.dir/urclock.c.o
[ 75%] Building C object src/CMakeFiles/libavrdude.dir/usbasp.c.o
[ 77%] Building C object src/CMakeFiles/libavrdude.dir/usb_hidapi.c.o
[ 78%] Building C object src/CMakeFiles/libavrdude.dir/usb_libusb.c.o
[ 80%] Building C object src/CMakeFiles/libavrdude.dir/usbtiny.c.o
[ 81%] Building C object src/CMakeFiles/libavrdude.dir/update.c.o
[ 83%] Building C object src/CMakeFiles/libavrdude.dir/wiring.c.o
[ 84%] Building C object src/CMakeFiles/libavrdude.dir/xbee.c.o
[ 86%] Building C object src/CMakeFiles/libavrdude.dir/__/lexer.c.o
[ 87%] Building C object src/CMakeFiles/libavrdude.dir/__/config_gram.c.o
[ 89%] Linking C static library libavrdude.a
[ 89%] Built target libavrdude
Scanning dependencies of target avrdude
[ 90%] Building C object src/CMakeFiles/avrdude.dir/main.c.o
[ 92%] Building C object src/CMakeFiles/avrdude.dir/term.c.o
[ 93%] Building C object src/CMakeFiles/avrdude.dir/avrintel.c.o
[ 95%] Building C object src/CMakeFiles/avrdude.dir/developer_opts.c.o
[ 96%] Building C object src/CMakeFiles/avrdude.dir/whereami.c.o
[ 98%] Linking C executable avrdude
[ 98%] Built target avrdude
Scanning dependencies of target conf
[100%] Generating avrdude.conf
[100%] Built target conf
mcuee commented 1 year ago

The PR certainly does not interfere with messaging. Have you ensured you rebuilt avrdude from scratch? Not doing so is a common cause for tests that go wrong.

Yes I have done that. I believe it has something to do with the change to config.txt even though I have reverted it and reboot.

In any case, as you mentioned, it is not related to PR #1231 and it is good to merge PR #1231 now.

Further tests with a new setup with Raspberry Pi 400 confirms this PR is the issue. But I am not so sure how to fix it.

MCUdude commented 1 year ago

Fixed in #1231