{"id":31120828,"url":"https://github.com/askn37/jtag2updi","last_synced_at":"2025-09-17T15:03:46.047Z","repository":{"id":209580770,"uuid":"724441836","full_name":"askn37/jtag2updi","owner":"askn37","description":"JTAG2UPDI clone with support for NVMCTRL versions 0, 2, 3, 4, and 5","archived":false,"fork":false,"pushed_at":"2024-08-14T13:09:49.000Z","size":233,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-08-15T13:52:58.496Z","etag":null,"topics":["atmel","avr","avr-du","microchip","updi"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/askn37.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-28T04:40:37.000Z","updated_at":"2024-08-15T09:05:54.000Z","dependencies_parsed_at":"2023-12-19T05:39:44.438Z","dependency_job_id":"46cb966f-2a65-4820-a0c6-712adb43f895","html_url":"https://github.com/askn37/jtag2updi","commit_stats":null,"previous_names":["askn37/jtag2updi"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/askn37/jtag2updi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askn37%2Fjtag2updi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askn37%2Fjtag2updi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askn37%2Fjtag2updi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askn37%2Fjtag2updi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/askn37","download_url":"https://codeload.github.com/askn37/jtag2updi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askn37%2Fjtag2updi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275615138,"owners_count":25496810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atmel","avr","avr-du","microchip","updi"],"created_at":"2025-09-17T15:02:14.015Z","updated_at":"2025-09-17T15:03:46.041Z","avatar_url":"https://github.com/askn37.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# JTAG2UPDI (Clone)\n\n- [READEME of the original (en_US)](README_orig.md)\n- [English version of this document (en_US)](README.md)\n- [Japanese version of this document (ja_JP)](README_jp.md)\n\nThis is a static fork of the [ElTangas/jtag2updi](https://github.com/ElTangas/jtag2updi) firmware. Although most of the code is the same, there is no upstream linkage as it involves large-scale changes.\n\nBranching point: https://github.com/ElTangas/jtag2updi/tree/07be876105e0b9cfedf2723b0ac88780bcae50d8\n\nThe difference between the two should be obtained by `diff -uBw jtag2updi-master/source jtag2updi-main/src`. `JTAG2.cpp` is almost completely different.\n\n## What has changed\n\n- Compatible with NVMCTRL version 0,2,3,4,5. The correspondence in the original text is up to 0 and 2.\n   - Support tinyAVR-0/1/2, megaAVR-0, AVR_DA/DB/DD/EA/EB.\n     - Compatible with UPDI layer SIB (System Information Block).\n   - AVR_DU (NVMCTRLv4) support is provisional/experimental as of December 2023.\n   - Main devices confirmed to work: ATtiny202 ATtiny412 ATtiny824 ATtiny1614 ATmega4809 AVR32DA32 AVR128DB32 AVR32DD14 AVR64DD32 AVR64EA32 (as of November 2023)\n- Compatible with AVRDUDE 7.3.\n   - Operation confirmed: `AVRDUDE` `7.2`, `7.3` (under development as of November 2023)\n   - For `6.8` and earlier, use with a specially modified configuration file. Starting from `7.0`, the standard configuration file is sufficient.\n   - Only partial memory blocks can be rewritten using the `-D` option. (as the bootloader does)\n     - This allows you to also use the `write/elase \u003cmemtyp\u003e` command in interactive mode.\n   - Compatible with locked devices.\n     - Blind writing of USERROW.\n     - LOCK_BITS Lock/Unlock.\n   - Enhanced memory range specification violation detection.\n     - Allow 256 word FLASH bulk reading/writing of AVR_DA/DB/DD.\n     - Allows 1 word EEPROM reading/writing of AVR_DA/DB/DD. (Standard configuration file is limited to 1 byte unit)\n     - Allows 4 word EEPROM reading/writing of AVR_EA/EB.\n   - `230400`, `460800`, and `500000` can be practically specified in many environments with the `-b` option.\n     - This does not apply to Arduino compatible machines. Please note that when reading and writing large-capacity bulk, you are subject to host-side timeout/error restrictions. (Generally, the faster the communication speed, the higher the USB packet loss rate)\n   - Some enhancements.\n     - Does not support high voltage control. This requires additional hardware and specialized control code. He has two different specifications for his HV control for current UPDI-enabled devices. There is no easy way to support both at the same time, which makes the problem difficult. (See UPDI4AVR technical information)\n- Firmware build and installation has been verified only for Arduino IDE 1.8.x/2.x. Not sure about other methods.\n   - The `source` directory has been changed to `src` to match the Arduino IDE specifications. The location of the `jtag2updi.ino` file is also different.\n   - Attached files that are not supported have been removed. Please copy from the original if necessary.\n\nEquipment that can be installed with firmware:\n\n- ATmegaX8 series --- Arduino UNO Rev.3, Arduino Mini, Arduino Micro (ATmega328P)\n- megaAVR-0 series --- Arduino UNO WiFi Rev.2 (ATmega4809)\n- AVR_DA/DB Series --- Microchip Curio City\n\n\u003e After installing the firmware, we recommend installing an additional 10uF capacitor between /RESET and GND to disable the auto-reset function.\n\nMany of the technical elements come from the knowledge gained from the process of developing [UPDI4AVR](https://github.com/askn37/multix-zinnia-updi4avr-firmware-builder/).\nSince UPDI4AVR can only be installed on megaAVR-0 or later devices, his JTAG2UPDI (Clone) was created to make effective use of old Arduino.\n\n## Technical information\n\n### NVMCTRL\n\nNVMCTRL specifications differ depending on each system. The versions are classified into versions 0 to 5, depending on the number read from the SIB. They are not compatible with each other because they have different control register positions and definition values, and different control methods.\n\nA list of control register definitions for each version is shown below.\n\n|Offset|version 0|version 2|version 3|version 4|version 5|\n|-|-|-|-|-|-|\n|Series|(tiny,mega)AVR|AVR_DA/DB/DD|AVR_EA|AVR_DU|AVR_EB\n|$00|CTRLA|CTRLA|CTRLA|CTRLA|CTRLA\n|$01|CTRLB|CTRLB|CTRLB|CTRLB|CTRLB\n|$02|STATUS|STATUS|-|CTRLC|CTRLC\n|$03|INTCTRL|INTCTRL|-|-|-\n|$04|INTFLAGS|INTFLAGS|INTCTRL|INTCTRL|INTCTRL\n|$05|-|-|INTFLAGS|INTFLAGS|INTFLAGS\n|$06|DATAL|DATAL|STATUS|STATUS|STATUS\n|$07|DATAH|DATAH|-|-|-\n|$08|ADDRL|ADDR0|DATAL|DATA0|DATAL\n|$09|ADDRH|ADDR1|DATAH|DATA1|DATAH\n|$0A|-|ADDR2|-|DATA2|-\n|$0B|-|_ADDR3_|-|DATA3|-\n|$0C|-|-|ADDR0|ADDR0|ADDR0\n|$0D|-|-|ADDR1|ADDR1|ADDR1\n|$0E|-|-|ADDR2|ADDR2|ADDR2\n|$0F|-|-|_ADDR3_|_ADDR3_|_ADDR3_\n\n\u003e Symbols in italics are defined but do not actually function. Should always be zero.\\\n\u003e No known implementation of version 1.\n\nThe most significant bit of `NVMCTRL_ADDR2` has a special meaning: 0 is used as a flag to specify the address of the general data area, and 1 is used as a flag to specify the address of the FLASH code area (currently up to 128KiB). Version 0 does not have this, and data and code are not differentiated within the same 64KiB space.\n\nIn all versions, FLASH memory is word-oriented. Operations that do not follow word alignment will not yield the expected results.\n\nNVM writing writes memory data directly to the target address (using UPDI's ST/STS command or assembly's ST/SPM command). Then, the specified address is reflected in the ADDR register, the memory data is reflected in the DATA register, and then passed to internal transfer processing.\n\n#### NVMCTRL version 0\n\nThis system is the only one with a 16-bit address bus system, and the code space is within 64 KiB, the same as the data space. However, the actual code area start address offset starts from 0x8000 for the tinyAVR series and 0x4000 for the megaAVR series, so the two must be treated separately.\n\nIn addition, this system has the following characteristics:\n\n-Has a special working buffer memory that does not appear in memory space and is shared by FLASH and his EEPROM.\n- You can continue to write memory data to both FLASH and EEPROM as long as the buffer memory range is not exceeded.\n- After filling the buffer memory, write the desired command code to CTRLA. When the controller is activated and the target processing is completed, the processing result is reflected in the STATUS register. The controller is deactivated at the end of processing.\n- EEPROM can also be written in bulk with the same page granularity as FLASH, resulting in faster processing.\n-USERROW can be written using the same command code as EEPROM. (However, you should use a specially prepared method.)\n- FUSE memory has special dedicated write commands. After writing directly to the DATA and ADDR registers, he writes a dedicated command to CTRLA.\n- There is no SPM instruction in the AVR instruction set. Equivalent to NOP instead of undefined. On the other hand, since there is an LPM instruction, he can read the FLASH area relative to the start address of the code area.\n\n#### NVMCTRL version 2\n\nThis system has no working buffer memory. It has only one word buffer (that is, DATAL/H register). Therefore, the processing procedure is different.\n\n- Write the desired command code to CTRLA and activate the controller.\n- Write memory data to the target NVM address using ST/SPM instructions.\n- Check the STATUS register, and after completing the desired processing, write the NOCMD (or NOOP) command to CTRLA to stop the controller.\n- Memory data can be written continuously in the FLASH area as long as it does not exceed the page range.\n- In the EEPROM area, only 1 word granularity (within 2 bytes) can be written continuously.\n- FUSE can be written using the same command codes as EEPROM.\n- USERROW can be written using the same command code as FLASH. (However, you should use a specially prepared method.)\n\nThis family has a FLASH page granularity of 512 bytes. However, since NVM writers that support this size are not common, `AVRDUDE` attempts to write his data in two 256-byte blocks.\n\n#### NVMCTRL version 3,5\n\nThis system has different working buffer memories for his FLASH and EEPROM. Therefore, memory data can be written continuously within that page range.\n\n- Write a NOCMD (or NOOP) command to CTRLA to ensure controller deactivation.\n- Write memory data to the target NVM address using ST/SPM instructions.\n-Both FLASH and his EEPROM can write memory data continuously as long as they do not exceed their respective buffer memory ranges (128 bytes and 8 bytes).\n- After filling the buffer memory, write the desired command code to CTRLA. When the controller is activated and the target processing is completed, the processing result is reflected in the STATUS register. The controller is deactivated at the end of processing.\n- FUSE can be written using the same command codes as EEPROM.\n- USERROW can be written using the same command code as FLASH. (However, you should use a specially prepared method.)\n- BOOTROW (specific to version 5) uses the same directive codes as FLASH.\n\nIn his NVM rewriting work from UPDI, he does not use CTRLC, so versions 3 and 5 can share the same control processing. However, since many of the physical addresses in the NVM area are different, they are handled differently.\n\n#### NVMCTRL version 4\n\nThis family has version 5 of the NVMCTRL register file and version 2 of the NVMCTRL command set. It is implemented in AVR_DU, but the usage is (probably) based on version 2. However, since many of the actual addresses in the NVM area are different, they are handled differently.\n\nThis system has no working buffer memory. Since the DATA register has 2 words, EEPROM can (probably) be written in 4-byte units.\n\nThis family has a FLASH page granularity of 512 bytes. However, since NVM writers that support this size are not common, `AVRDUDE` attempts to write his data in two 256-byte blocks.\n\n### Partial memory block write\n\nTo be able to use the `-D` option of `AVRDUDE` and the `write/erase \u003cmemtype\u003e` command in interactive mode, each memory area must support page erasure. The original JTAG2UPDI could not handle these. What it actually does is what a typical bootloader would do: first erase the page at the specified address, then write the given data to its memory.\n\n\u003e JTAGICE mkII's original XMEGA memory page erase instruction is not used in `AVRDUDE`. Instead, normal memory read/write instructions are used instead.\n\nAt this time, in the case of a 512-byte page, since `AVRDUDE` is designed to divide the data into multiple memory blocks and send the data, consideration must be given to determining whether or not the page can be erased depending on the starting address. For the same reason, if a setting different from the page granularity of the actual device is written in the `AVRDUDE` configuration file, partial memory block writing will not show the correct processing result (the buffer contents will become invalid).\n\n### Locked device compatible\n\n\"Device locking\" is one of the functions implemented in devices mainly for security reasons. Locking prevents unauthorized tampering or reading of the contents of the flash memory or EEPROM stored in the device. However, access to UPDI is not denied, and full chip erase and blind writes to the USERROW area are permitted.\n\nTo lock the device, simply change the LOCK_BITS field to a value other than the default.\n\n```sh\n# Device lock operation\n$ avrdude ... -U lock:w:0:m\n```\n\nFor locked devices, only writing to the USERROW area is allowed. Since reading is not allowed, readback verification is not possible. In other words, you need at least the triple option `-F -V -U`. Only the application previously written to the device can know whether the writing was successful or not.\n\nOn the other hand, device signatures cannot be read from locked devices. If there is no `-F` option, you will not be able to proceed with any further operations.\n\nNote that in the case of JTAG2UPDI (Clone), a false signature (when `ENABLE_PSEUDO_SIGNATURE` is enabled) is returned from the locked device, so for example, in the case of a locked ATmega4809, the following hint can be obtained (probably).\n\n```plain\n$ avrdude ... -FVU userrow:w:12,34,56,78:m\n\navrdude warning: bad response to enter progmode command: RSP_ILLEGAL_MCU_STATE\navrdude warning: bad response to enter progmode command: RSP_ILLEGAL_MCU_STATE\navrdude: AVR device initialized and ready to accept instructions\navrdude: device signature = 0x1e6d30 (probably megaAVR-0 locked device)\navrdude warning: expected signature for ATmega4809 is 1E 96 51\n\navrdude: processing -U userrow:w:12,34,56,78:m\navrdude: reading input file 12,34,56,78 for userrow/usersig\n         with 4 bytes in 1 section within [0, 3]\n         using 1 page and 60 pad bytes\navrdude: writing 4 bytes userrow/usersig ...\nWriting | ################################################## | 100% 0.01 s\navrdude: 4 bytes of userrow/usersig written\n\navrdude done.  Thank you.\n```\n\nTo unlock a locked device, use the `-e -F` options to force a full chip erase. The lock key will be reset to its initial value, but it may not be reflected correctly unless the power is turned off once (because it is a FUSE area). If you want to unlock and restore the flash at the same time, it is a good idea to write the correct lock key with `-U` first.\n\n```sh\n# Device unlock operation (chip erase)\n$ avrdude ... -eF\n```\n\n\u003e [!TIP]\n\u003e If you disable the UPDI control pin in the FUSE settings, the JTAG2UPDI implementation cannot override this and restore it.\n\n\u003e [!CAUTION]\n\u003e For the AVR-DU/EB family, if you lock the device when `FUSE_PDICFG` is not the default, you will never be able to perform UPDI operations again.\n\n### Enhanced memory range specification violation detection\n\nThis is a function that specifically rejects the specification of an unacceptable amount of write/read data. If rejected, `AVRDUDE` often falls back to single-byte read/write operations, so this is intentionally controlled from the JTAG2UPDI side. The cause of the error is usually a mistake in editing the configuration file or a mistake in specifying parts.\n\n- Do not allow reading or writing of 0 bytes. This shouldn't happen unless you set it intentionally. (but not impossible)\n- Do not allow EEPROM writes with data lengths exceeding the true (limited by NVMCTRL version) page granularity.\n- Writing to the FLASH area is prohibited unless it matches the page granularity or a special defined value.\n\n### CMND_GET_PARAMETER\n\nSupports `PAR_TARGET_SIGNATURE` inquiry. This reads and returns the SIB (System Information Block) from UPDI if possible. SIB is not a general memory read, so using `CMND_GET_PARAMETER` does not violate the JTAGICE mkII protocol rules. The returned data length is 32 bytes, unlike `PDI/SPI` devices (which are fixed at 2 bytes).\n\n\u003e For `PP/HV/PDI/SPI` devices, the `PAR_TARGET_SIGNATURE` query is used because the device signature cannot be read by normal memory reading. Devices from the XMEGA generation onwards do not use the device signature, as it is located in the normal IO memory area, and instead use normal memory reads.\n\n### Handling of AVR EA/EB series\n\nThere are many potentially fatal design errors and many hidden (or undiscovered) silicon errata.\nPlease note the following points regarding NVM operations.\n\n- There is a fatal errata in the CRCSCAN peripheral function. This should not be enabled by changing FUSE_SYSCFG0. Fixed in AVR EA with latest production lot.\n- With __AVR_EB__, the chip erase function in the UPDI peripheral function does not work properly. Chip erase of NVMCTRL peripheral function works normally.\n- In __AVR_EB__, LOCK.KEY and FUSE.PDICFG do not work as per public information.\nIt is assumed that this was a design error in the LOCK.KEY function along with the chip erasure issue.\nRewriting these fuses easily bricks the chip and there is no way to recover.\n\n## Build options\n\nThese macro declarations are provided in `sys.h`.\n\n### NO_ACK_WRITE\n\nEnabled by default. Allow UPDI bulk data writing. Disabling it will reduce memory write speed by half, but that is the only effect.\n\n### DISABLE_HOST_TIMEOUT\n\nDisabled by default. Client side JATG communication timeout is not limited. This is useful when using interactive mode a lot. However, if the host implements his keepalive, there is no need to enable it.\n\n\u003e If you cannot succeed without lowering the UPDI communication speed, the wiring load is excessive. This can usually be improved by removing excessive series resistors and pull-up resistors and making the wiring short enough.\n\n### DISABLE_TARGET_TIMEOUT\n\nDisabled by default. Do not limit UDPI communication timeout. It should not be used as it has significant side effects.\n\n### INCLUDE_EXTRA_INFO_JTAG\n\nDisabled by default. Add the obtained detailed device information to the response of the `SET_DEVICE_DESCRIPTPOR` packet. If you run `AVRDUDE` with `-vvvv`, it will be displayed, but it is not human readable.\n\n### ENABLE_PSEUDO_SIGNATURE\n\nEnabled by default. If UDPI is not disabled and the device is locked, a pseudo device signature will be returned. The following six types of pseudo signatures are currently generated.\n\n|Signature|Description|\n|-|-|\n|0x1e 0x74 0x30|Locked tinyAVR-0/1/2\n|0x1e 0x6d 0x30|Locked megaAVR-0\n|0x1e 0x41 0x32|Locked AVR_DA/DB/DD\n|0x1e 0x41 0x33|Locked AVR_EA\n|0x1e 0x41 0x34|Locked AVR_DU\n|0x1e 0x41 0x35|Locked AVR_EB\n\nBy adding the corresponding part settings to the configuration file, you will be able to easily visualize the differences. At the same time, this is also a summary of the only SIB that can be obtained from a locking device, making it clear that the device can be unlocked without HV control.\n\n```sh\n#------------------------------------------------------------\n# Locked device pseudo signature\n#------------------------------------------------------------\n\npart\n    id        = \"tinyAVR-0/1/2 locked device\";\n    signature = 0x1e 0x74 0x30;\n;\n\npart\n    id        = \"megaAVR-0 locked device\";\n    signature = 0x1e 0x6d 0x30;\n;\n\npart\n    id        = \"AVR-DA/DB/DD locked device\";\n    signature = 0x1e 0x41 0x32;\n;\n\npart\n    id        = \"AVR-EA locked device\";\n    signature = 0x1e 0x41 0x33;\n;\n\npart\n    id        = \"AVR-DU locked device\";\n    signature = 0x1e 0x41 0x34;\n;\n\npart\n    id        = \"AVR-EB locked device\";\n    signature = 0x1e 0x41 0x35;\n;\n```\n\nWhen this feature is disabled, the device signature always responds with `0xff 0xff 0xff`.\n\n## Change log\n\n- 2024/08/15 Fixed AVR_DU compatibility (AVRDUDE 8.0 compliant)\n- 2024/01/26 NVM/V0 USERROW support fix\n- 2024/01/08 Chip erasure and notes added for AVR_EB\n- 2023/12/19 Added interim/experimental support for AVR_DU (for AVRDUDE 7.4)\n- 2023/11/28 First edition\n\n## Copyright and Contact\n\nTwitter(X): [@askn37](https://twitter.com/askn37) \\\nBlueSky Social: [@multix.jp](https://bsky.app/profile/multix.jp) \\\nGitHub: [https://github.com/askn37/](https://github.com/askn37/) \\\nProduct: [https://askn37.github.io/](https://askn37.github.io/)\n\nCopyright (c) 2024 askn (K.Sato) multix.jp \\\nReleased under the MIT license \\\n[https://opensource.org/licenses/mit-license.php](https://opensource.org/licenses/mit-license.php) \\\n[https://www.oshwa.org/](https://www.oshwa.org/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskn37%2Fjtag2updi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faskn37%2Fjtag2updi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskn37%2Fjtag2updi/lists"}