arduino:how-to-fix-a-usb-isp-programmer-and-make-it-work-with-arduino-ide-on-linux
Differences
This shows you the differences between two versions of the page.
Previous revision | |||
— | arduino:how-to-fix-a-usb-isp-programmer-and-make-it-work-with-arduino-ide-on-linux [2024/11/22 12:02] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== How to fix a USB-ISP programmer and make it work as USBasp with Arduino IDE on Linux ====== | ||
+ | ===== Introduction ===== | ||
+ | |||
+ | Although I do not usually program chips, because I prefer to use complete modules, mainly for utilizing their USB port as a user interface, I happened to work on a few projects with a bare ATtiny85, which requires a programmer. I managed with a custom programmer, built on an Arduino Nano loaded with '' | ||
+ | |||
+ | So, I was tired of having bare PCBs and wires all over the place, therefore I decided to order a USB programmer in a brightly colored metal case. The device I ordered was described as **" | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | I assumed that it would be the [[https:// | ||
+ | |||
+ | After the product arrived, I tested it, considering it would function as a USBasp, but it would not work. Its light remained red at all times, not showing any sign of activity. I am working on a Linux Mint desktop and dmesg reported the USB device as: | ||
+ | |||
+ | < | ||
+ | $ dmesg | ||
+ | ..... | ||
+ | usb 3-1: new low-speed USB device number 3 using ohci-platform | ||
+ | usb 3-1: New USB device found, idVendor=03eb, | ||
+ | usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 | ||
+ | usb 3-1: Product: USBHID | ||
+ | usb 3-1: Manufacturer: | ||
+ | </ | ||
+ | |||
+ | Googling the name of the manufacturer **" | ||
+ | |||
+ | Luckily, I did not have to re-invent the wheel because there has been a lot of excellent work. I decided to publish this article because: | ||
+ | |||
+ | - I did not find online explicit information regarding the version of the PCB inside the USB-ISP (v5.00) | ||
+ | - I have encountered many problems in the process and I had to consult several online sources. So I decided to gather in one place the complete procedure. | ||
+ | |||
+ | In order to make the device work on Linux and communicate with the Arduino IDE via avrdude, the solution is to re-flash the firmware of the USB-ISP, in order to make it behave as a USBasp, which in turn is recognized by avrdude. Luckily, we can use the pins of the exposed connector, as well as make an wire bridge to accomplish this re-flashing. | ||
+ | |||
+ | Note: avrdude has also an option to support programmers of type '' | ||
+ | |||
+ | < | ||
+ | $ avrdude -c ? | ||
+ | </ | ||
+ | |||
+ | So, to have a programmer, you need another programmer to re-flash it with the proper firmware! | ||
+ | |||
+ | To avoid any misconceptions: | ||
+ | |||
+ | * **USB-ISP** is the programmer device with the nice colored aluminum casing, | ||
+ | * **USBasp** is the firmware created by Thomas Fischl | ||
+ | * **ArduinoISP** is the sketch in //'' | ||
+ | |||
+ | The target audience for this article is mainly hobbyists. My opinion is that this device is by no means suitable for any corporate environment for production usage. | ||
+ | |||
+ | ===== References: ===== | ||
+ | |||
+ | - [[http:// | ||
+ | - [[https:// | ||
+ | - [[https:// | ||
+ | - [[https:// | ||
+ | - [[https:// | ||
+ | - [[http:// | ||
+ | - [[https:// | ||
+ | |||
+ | ===== Prerequisites: | ||
+ | |||
+ | The controller inside my USB-ISP is an **ATmega88**. As found online, other models have an **ATmega8**. Just remember it when you construct the parameters at the commands below. | ||
+ | |||
+ | You will need: | ||
+ | |||
+ | - A programmer able to flash the controller of USB-ISP. I used an Arduino Nano running " | ||
+ | - A 10-wire ribbon cable with female connectors on each side. In my case, it came with the USB-ISP. | ||
+ | - Dupont wires (female on the Arduino Nano side - male on the ribbon cable side. For an Uno, male on the Arduino Uno side - male on the ribbon cable side) | ||
+ | - A passive programming board. This is normally a ZIF socket or a breadboard which accomodates the chip that we want to program with our programmer and is wired to SCK, MISO, MOSI, RESET, as well as GND and Vcc. See also [[https:// | ||
+ | - A spare MCU, to test our new programmer. My passive programming board is not equipped with a crystal, because I work a lot with the minimal configuration and without bootloaders, | ||
+ | |||
+ | ===== WARNING ===== | ||
+ | |||
+ | If you brick an MCU because you selected an improper clock source, there are solutions to revive your chip, but this is another story. Just keep in mind that the MCU which we are programming **needs its own working clock source at all times**. The signal SCK is only used for timing the SPI interface and **it is not a substitute for the MCU clock source**. | ||
+ | |||
+ | Proceed at your own risk. | ||
+ | |||
+ | Be cautious regarding the licensing of the USBasp firmware and especially the [[https:// | ||
+ | | ||
+ | ===== Step 1. Identify your programming environment ===== | ||
+ | |||
+ | Locate the path of '' | ||
+ | |||
+ | Try: | ||
+ | |||
+ | < | ||
+ | $ sudo find / -name avrdude -print | ||
+ | $ sudo find / -name avrdude.conf -print | ||
+ | </ | ||
+ | |||
+ | The executable is at '' | ||
+ | |||
+ | < | ||
+ | .arduino15/ | ||
+ | .arduino15/ | ||
+ | </ | ||
+ | |||
+ | From all these copies, we only care about the one that is used by our Arduino IDE. To identify it, start the Arduino IDE. Select ''// | ||
+ | |||
+ | Load the **Blink** example and upload it to a board, as usual. Notice the messages appearing in the message pane and find the path from where the avrdude runs, along with all avrdude options that are created automatically by the IDE. In my case, it was: | ||
+ | |||
+ | < | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | where I substituted my home directory with ''/ | ||
+ | |||
+ | There are several other parameters but at this stage we only care abut the configuration file, which is provided with option '' | ||
+ | |||
+ | You can leave the ''// | ||
+ | |||
+ | Locate also the path of file '' | ||
+ | |||
+ | ===== Step 2. Prepare your programmer ===== | ||
+ | |||
+ | - If you use an Arduino board as programmer, upload the ArduinoISP sketch onto your Arduino board. | ||
+ | - Wire up the Arduino board with the connector on one side of the ribbon cable. | ||
+ | |||
+ | < | ||
+ | Arduino | ||
+ | |||
+ | Vcc (+5V) 2 Vcc | ||
+ | GND 4 GND | ||
+ | MISO (12) 9 MISO | ||
+ | MOSI (11) 1 MOSI | ||
+ | SCK (13) 7 SCK | ||
+ | (10) 5 RST | ||
+ | </ | ||
+ | |||
+ | Be extra cautious about the numbering of the connector pins. Usually, there will be an arrow or a triangle marker imprinted on the connector that will mark pin number 1. This photo will help: | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Note the location of pin 1 in respect to the notch. | ||
+ | |||
+ | I have also wired a 10uF capacitor between pins RESET and GND of the Nano during my attempts to make things work but this is not necessary. | ||
+ | |||
+ | ===== Step 3. Prepare the USB-ISP ===== | ||
+ | |||
+ | Push the USB connector and the PCB will come out from the box header side. | ||
+ | |||
+ | |||
+ | {{ : | ||
+ | |||
+ | After taking it out, I noticed that it contains an ATMega88 running at a 12 MHz crystal and the PCB states that it is **MX-U2BLSP-V5.00**, | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Using a very thin wire, solder the two pins on the USB-ISP PCB that are marked as "-> UP < | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | Do not connect any cable yet and leave the USB connector unconnected. | ||
+ | |||
+ | |||
+ | ===== Step 4. Re-program USP-ISP with USBasp firmware ===== | ||
+ | |||
+ | Download [[https:// | ||
+ | |||
+ | Rename the file to " | ||
+ | |||
+ | < | ||
+ | $ mv usbasp.atmega88.2011-05-28.hex usbasp.atmega88.2011-05-28.original.hex | ||
+ | </ | ||
+ | |||
+ | Make a copy of the file: | ||
+ | |||
+ | < | ||
+ | $ cp usbasp.atmega88.2011-05-28.original.hex usbasp.atmega88.2011-05-28.hacked.hex | ||
+ | </ | ||
+ | |||
+ | Change the file permissions of the original file to read-only, so that we do not modify it by accident. | ||
+ | |||
+ | < | ||
+ | $ chmod 444 usbasp.atmega88.2011-05-28.original.hex | ||
+ | </ | ||
+ | |||
+ | Open '' | ||
+ | |||
+ | > | ||
+ | > In the ATmega88 HEX file, the corresponding code is located on line 185, and here’s the line with the bytes | ||
+ | > highlighted: | ||
+ | > | ||
+ | > : | ||
+ | > | ||
+ | > Let’s patch the code to set DDRD = 0b1111_0000, | ||
+ | > | ||
+ | > : | ||
+ | |||
+ | |||
+ | Now it is the time to flash the hacked hex file into the ATmega88. Go to the folder where avrdude is. Use your own path. Mine was: | ||
+ | |||
+ | < | ||
+ | $ cd ~/ | ||
+ | </ | ||
+ | |||
+ | Considering that your Arduino board is identified as device ''/ | ||
+ | |||
+ | < | ||
+ | $ ./avrdude -c stk500v1 -b 19200 -P/ | ||
+ | </ | ||
+ | |||
+ | Notice the parameters: | ||
+ | |||
+ | > -c stk500v1 -b 19200 : This is to make avrdude communicate with a Arduino ISP, implementing the stk500v1 protocol at 19200bps. We need this setting if our programmer is Arduino (Uno, Nano etc). If you are using another programmer, set the appropriate protocol | ||
+ | > -p atmega328 : This is because we still talk to our Arduino programmer (Uno or Nano) | ||
+ | > -vv : To enable verbose output | ||
+ | > -C ../ | ||
+ | |||
+ | |||
+ | We must have an output like this: | ||
+ | |||
+ | < | ||
+ | avrdude: Version 6.3-20190619 | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | User configuration file is "/ | ||
+ | User configuration file does not exist or is not a regular file, skipping | ||
+ | |||
+ | Using Port : / | ||
+ | Using Programmer | ||
+ | | ||
+ | AVR Part : ATmega328 | ||
+ | Chip Erase delay : 9000 us | ||
+ | | ||
+ | | ||
+ | RESET disposition | ||
+ | RETRY pulse : SCK | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | Block Poll | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | SCK period | ||
+ | |||
+ | avrdude: AVR device initialized and ready to accept instructions | ||
+ | |||
+ | Reading | ################################################## | ||
+ | |||
+ | avrdude: Device signature = 0xff00ff | ||
+ | avrdude: Expected signature for ATmega328 is 1E 95 14 | ||
+ | | ||
+ | |||
+ | avrdude done. Thank you. | ||
+ | </ | ||
+ | |||
+ | We are at the right track. | ||
+ | |||
+ | Insert the connector at the other end of the ribbon cable to the box header of the USB-ISP. NOTE: LEAVE THE USB CONNECTOR OF THE USB_ISP UNCONNECTED. The board will be powered by our Arduino programmer. | ||
+ | |||
+ | Run the command again. | ||
+ | |||
+ | < | ||
+ | $ ./avrdude -c stk500v1 -b 19200 -P/ | ||
+ | </ | ||
+ | |||
+ | At the end you shall see: | ||
+ | |||
+ | < | ||
+ | avrdude: Device signature = 0x1e930a (probably m88) | ||
+ | avrdude: Expected signature for ATmega328 is 1E 95 14 | ||
+ | | ||
+ | |||
+ | avrdude done. Thank you. | ||
+ | </ | ||
+ | |||
+ | The **" | ||
+ | |||
+ | Now it is time to talk to the ATmega88. Run the command, changing the processor definition from '' | ||
+ | |||
+ | < | ||
+ | $ ./avrdude -c stk500v1 -b 19200 -P/ | ||
+ | </ | ||
+ | |||
+ | At the end, we shall see: | ||
+ | |||
+ | < | ||
+ | avrdude: Device signature = 0x1e930a (probably m88) | ||
+ | avrdude: safemode: lfuse reads as FF | ||
+ | avrdude: safemode: hfuse reads as DD | ||
+ | avrdude: safemode: efuse reads as F9 | ||
+ | |||
+ | avrdude: safemode: lfuse reads as FF | ||
+ | avrdude: safemode: hfuse reads as DD | ||
+ | avrdude: safemode: efuse reads as F9 | ||
+ | avrdude: safemode: Fuses OK (E:F9, H:DD, L:FF) | ||
+ | </ | ||
+ | |||
+ | These are the signature and fuse settings of ATmega88. The USBasp firmware requires those fuses to be: **lfuse FF, hfuse DD**. It seems that the fuses are already programmed to the values that we want. If they were not, we could set them with avrdude, using the following parameters: | ||
+ | |||
+ | < | ||
+ | $ ./avrdude -c stk500v1 -b 19200 -P/ | ||
+ | </ | ||
+ | |||
+ | Read the original flash memory of the ATmega88 and save to file. This step is optional but we want first to make sure that we have proper communication and second to keep the current firmware, just in case we would like to restore it for any reason. We shall call this firmware " | ||
+ | |||
+ | < | ||
+ | $ ./avrdude -c stk500v1 -b 19200 -P/ | ||
+ | </ | ||
+ | |||
+ | Make the file read-only, just for protection. | ||
+ | |||
+ | < | ||
+ | $ chmod 444 / | ||
+ | </ | ||
+ | |||
+ | Now, program the USB-ISP with the hacked hex file containing the USB-ASP firmware: | ||
+ | |||
+ | < | ||
+ | $ ./avrdude -c stk500v1 -b 19200 -P/ | ||
+ | </ | ||
+ | |||
+ | The full output is: | ||
+ | |||
+ | < | ||
+ | avrdude: Version 6.3-20190619 | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | User configuration file is "/ | ||
+ | User configuration file does not exist or is not a regular file, skipping | ||
+ | |||
+ | Using Port : / | ||
+ | Using Programmer | ||
+ | | ||
+ | AVR Part : ATmega88 | ||
+ | Chip Erase delay : 9000 us | ||
+ | | ||
+ | | ||
+ | RESET disposition | ||
+ | RETRY pulse : SCK | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | Block Poll | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | SCK period | ||
+ | |||
+ | avrdude: AVR device initialized and ready to accept instructions | ||
+ | |||
+ | Reading | ################################################## | ||
+ | |||
+ | avrdude: Device signature = 0x1e930a (probably m88) | ||
+ | avrdude: safemode: lfuse reads as FF | ||
+ | avrdude: safemode: hfuse reads as DD | ||
+ | avrdude: safemode: efuse reads as F9 | ||
+ | avrdude: NOTE: " | ||
+ | To disable this feature, specify the -D option. | ||
+ | avrdude: erasing chip | ||
+ | avrdude: reading input file "/ | ||
+ | avrdude: writing flash (4716 bytes): | ||
+ | |||
+ | Writing | ################################################## | ||
+ | |||
+ | avrdude: 4716 bytes of flash written | ||
+ | avrdude: verifying flash memory against / | ||
+ | avrdude: load data flash data from input file / | ||
+ | avrdude: input file / | ||
+ | avrdude: reading on-chip flash data: | ||
+ | |||
+ | Reading | ################################################## | ||
+ | |||
+ | avrdude: verifying ... | ||
+ | avrdude: 4716 bytes of flash verified | ||
+ | |||
+ | avrdude: safemode: lfuse reads as FF | ||
+ | avrdude: safemode: hfuse reads as DD | ||
+ | avrdude: safemode: efuse reads as F9 | ||
+ | avrdude: safemode: Fuses OK (E:F9, H:DD, L:FF) | ||
+ | |||
+ | avrdude done. Thank you. | ||
+ | </ | ||
+ | |||
+ | Now, disconnect the IDC connector from USB-ISP. | ||
+ | |||
+ | Also disconnect the Arduino programmer from the USB port. We will not need it any longer. | ||
+ | |||
+ | Unsolder the wire bridge in the '' | ||
+ | |||
+ | It is time to connect USB-ISP to the PC USB port to see what we have done. If all is well, the LED should light BLUE, instead of red before. | ||
+ | |||
+ | See the report of the USB devices | ||
+ | |||
+ | < | ||
+ | $ lsusb | ||
+ | |||
+ | Bus 003 Device 005: ID 16c0:05dc Van Ooijen Technische Informatica shared ID for use with libusb | ||
+ | |||
+ | $ dmesg | ||
+ | |||
+ | [ 3104.019558] usb 3-1.3: new low-speed USB device number 6 using uhci_hcd | ||
+ | [ 3104.155292] usb 3-1.3: New USB device found, idVendor=16c0, | ||
+ | [ 3104.155297] usb 3-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 | ||
+ | [ 3104.155300] usb 3-1.3: Product: USBasp | ||
+ | [ 3104.155303] usb 3-1.3: Manufacturer: | ||
+ | </ | ||
+ | |||
+ | The device is now recognized as a USBasp with Manufacturer: | ||
+ | |||
+ | Assemple back the PCB into the metal casing. | ||
+ | |||
+ | We now have a functional USB-ISP programmer running the USBasp firmware. But we have not finished. We must make Arduino IDE able to use this device. | ||
+ | |||
+ | |||
+ | ===== Step 5. Fix Arduino IDE ===== | ||
+ | |||
+ | Start Arduino IDE, select ''//" | ||
+ | using ''// | ||
+ | |||
+ | You may get an error: | ||
+ | |||
+ | < | ||
+ | avrdude: Warning: cannot open USB device: Permission denied | ||
+ | </ | ||
+ | |||
+ | This means that we should instruct Linux to recognize the new USB device and allow users with non-root permission to access it. | ||
+ | |||
+ | In [[https:// | ||
+ | |||
+ | The instructions are to copy file '' | ||
+ | |||
+ | In addition, it was necessary to make the following two modifications in the contents of file '' | ||
+ | |||
+ | * replace SYSFS with ATTRS | ||
+ | * add GROUP=" | ||
+ | |||
+ | Use a text editor to make those changes and finally, '' | ||
+ | |||
+ | < | ||
+ | # USBasp - USB programmer for Atmel AVR controllers | ||
+ | |||
+ | SUBSYSTEM==" | ||
+ | </ | ||
+ | |||
+ | Now copy it to the destination folder: | ||
+ | |||
+ | < | ||
+ | $ sudo cp 99-USBasp.rules / | ||
+ | </ | ||
+ | |||
+ | Restart udev, or reboot. Use systemctl if your system runs on systemd | ||
+ | |||
+ | < | ||
+ | $ / | ||
+ | </ | ||
+ | |||
+ | Next problem: avrdude reports error | ||
+ | |||
+ | < | ||
+ | $ ./avrdude -c usbasp -p m328p -F -C ../ | ||
+ | ...... | ||
+ | avrdude: error: program enable: target doesn' | ||
+ | </ | ||
+ | |||
+ | With the avrdude '' | ||
+ | |||
+ | < | ||
+ | avrdude: Device signature = 0xc837d5 | ||
+ | avrdude: Expected signature for ATmega328P is 1E 95 0F | ||
+ | </ | ||
+ | |||
+ | The problem here is that the chip that we want to program is very slow and cannot respond at the speed of our programmer. Remember that an ATmega328 straight from the factory, without any bootloader, comes preset to 8MHz RC internal clock and CKDIV8 fuse programmed to 0, lowering the clock to 1MHz. To make avrdude speak " | ||
+ | |||
+ | From [[http:// | ||
+ | |||
+ | > -B bitclock | ||
+ | > | ||
+ | > Specify the bit clock period for the JTAG interface or the ISP clock (JTAG ICE only). The value is a > | ||
+ | |||
+ | |||
+ | So the solution is to add '' | ||
+ | |||
+ | Try again | ||
+ | |||
+ | < | ||
+ | $ ./avrdude -c usbasp -p m328p -F -C ../ | ||
+ | </ | ||
+ | |||
+ | and finally a response! | ||
+ | |||
+ | < | ||
+ | avrdude: set SCK frequency to 93750 Hz | ||
+ | avrdude: AVR device initialized and ready to accept instructions | ||
+ | |||
+ | Reading | ################################################## | ||
+ | |||
+ | avrdude: Device signature = 0x1e950f (probably m328p) | ||
+ | |||
+ | avrdude: safemode: Fuses OK (E:FF, H:D9, L:62) | ||
+ | |||
+ | avrdude done. Thank you. | ||
+ | </ | ||
+ | |||
+ | To make the solution permanent, several online articles instruct to modify avrdude.conf and set | ||
+ | |||
+ | < | ||
+ | default_bitclock = 10; | ||
+ | </ | ||
+ | |||
+ | But instead of messing with '' | ||
+ | |||
+ | Find section | ||
+ | |||
+ | < | ||
+ | usbasp.name=USBasp | ||
+ | usbasp.communication=usb | ||
+ | usbasp.protocol=usbasp | ||
+ | usbasp.program.protocol=usbasp | ||
+ | usbasp.program.tool=avrdude | ||
+ | usbasp.program.extra_params=-Pusb | ||
+ | </ | ||
+ | |||
+ | and modify the last line to: | ||
+ | |||
+ | < | ||
+ | usbasp.program.extra_params=-Pusb -B 10 | ||
+ | </ | ||
+ | |||
+ | This modification will force avrdude to set parameters '' | ||
+ | |||
+ | Finally, I selected //" | ||
+ | |||
+ | You now have a working USB-ISP programmer, running USBasp firmware and a fully functional Arduino IDE. | ||
+ | |||
+ | ====== Summary ====== | ||
+ | |||
+ | The original purpose was to purchase a cheap programmer to avoid the clutter of having an Arduino Nano and a bunch of cables, and to avoid wiring manually every time I wished to program an MCU. The result was that I really needed the Nano in order to re-flash the firmware of the USB-ISP and additionally, | ||
+ | |||
+ | In spite of the fact that now I am the //proud// owner of a USBasp programmer, which along with a ZIF socket will allow me to make my programming process easier (alas only in particular cases because it is not a professional programmer), | ||
+ | |||
+ | Have fun... | ||
+ | |||
+ | ~~DISQUS~~ |