ElTangas / jtag2updi

UPDI programmer software for Arduino (targets Tiny AVR-0/1/2, Mega AVR-0 and AVR-DA/DB MCUs)
MIT License
329 stars 90 forks source link

The programmer is not able to unbrick locked tinyAVR MCU at all #61

Open kosilin opened 2 years ago

kosilin commented 2 years ago

Good day!

I mean the MCU having lock byte set. At least when using avrdude.

The reason is code of JTAG2::enter_progmode(). Briefly: this code is not working completely if the MCU is in "locked" state even using HV-programmer.

Please give me few days to rewrite the function in a way it can handle "locked MCU" condition correctly.

Best regards, Alexey

kosilin commented 2 years ago

Good day!

So, I've performed some investigation of the problem and can suggest now some solution of it...

Mainly the core of the problem lies in avrdude 6.3 code that wants very much to readout device signature before it can do something else. But in case a target is locked it doesn't allow to readout anything (and of course the target can't be switched into nvram programming mode)! It's the problem.

So, I can suggest following solution of this problem: in a few words it's necessary just to replace real memory reading by fake data (zeros) in case the MCU is locked. That's all!

It's very nice that avrdude doesn't require successful enter_prog_mode call. Because of this the changes in programmer firmware can be minimal.

Please see to difference file i've attached . JTAG2.cpp.diff.txt

I've slightly improved JTAG2::enter_progmode() just because it's more correct as I think, and also I've changed JTAG2::read_mem() enabling the function to return fake zeroes in case the target is locked.

May be this solution is not an ideal, but as alternative I see just one way - to contribute in avrdude development in order to develop special UPDI driver.

So, I'll be glad if you'll take in account my proposal especially taking in account the fact that it's not required to have HV-programmer in order to unbrick simply locked MCUs.

P.S. Please pay attention to using -F command-line switch using avrdude:

avrdude -p t1616 -c jtag2updi -P /dev/ttyUSB0 -e -F

avrdude: AVR device initialized and ready to accept instructions

Reading | | 0% 0.00savrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_ILLEGAL_MCU_STATE avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_ILLEGAL_MCU_STATE Reading | ################################################## | 100% 0.07s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.05s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.04s

avrdude: Device signature = 0x000000 avrdude: Yikes! Invalid device signature. avrdude: Expected signature for ATtiny1616 is 1E 94 21 avrdude: erasing chip

avrdude done. Thank you.

Best regards, Alexey

ElTangas commented 2 years ago

So have you tried the method I explain in the documentation?

Alternatively, you can erase the chip from interactive mode, enter it using "-t", and "-F" to override the error: Note: You must build with DISABLE_HOST_TIMEOUT defined for terminal mode to work. See below for more information on the timeouts.

edit: there is indeed a bug of missing packet.size_word[0] = 2; I will correct this first, then think about your proposal.

kosilin commented 2 years ago

Good day!

As it was seemed to me the avrdude will not even enter in terminal mode in case it can't read a target signature. I supposed this based on analysis of avrdude sources. But I definitely shall try to make this test at this weekend and I'll tell you about it results.

[upd]

edit: there is indeed a bug of missing packet.size_word[0] = 2; I will correct this first, then think about your proposal.

But what also about using 0xEF (0xEE) mask of MCU state? I think there is also some issue in this code: because of this at least the additional checking MCU state in branch 0x82 of switch operator is the dead code in a fact.

Best regards, Alexey

ElTangas commented 2 years ago

But what also about using 0xEF (0xEE) mask of MCU state? I think there is also some issue in this code: because of this at least the additional checking MCU state in branch 0x82 of switch operator is the dead code in a fact.

Ah ok I see maybe it's dead maybe not. This part of the code had lots of bugs and there are some quirks in UPDI the lock bit may become 1 at a later stage, or maybe not and you are right. I don't remember. actually...

Yes I think there is a chance, the chip was not locked when the lock bit is checked for the first time, but is changed and the next reset will make it active. That code is most likely not there by chance I won't risk removing it.

edit: However you are right in the sense it's confusing. I should add a comment explaining a chip reset may enable the lock bit and that's why it needs to be checked again.

kosilin commented 2 years ago

Good day!

Okay... I've understood your idea. No questions more. Just the code looks a little bit strange... No matter )))

What 'bout terminal mode of avrdude: I was wrong - it's really activated and even there is no attempts to readout the target signature! I've amazed. Nevertheless I think my proposal is more or less actual: it would be great if there is a way to erase MCU without DISABLE_HOST_TIMEOUT definition and also without performing additional tasks by fingers.

Best regards, Alexey

P.S. Anyway, thanks for the dialogue and also your comments! ))

ElTangas commented 2 years ago

Just the code looks a little bit strange...

I know. That's because of so many previous bug fixes and adapting to avrdude and UPDI quirks. Each one makes the code more cryptic and strange. Let's say I add your suggestion. The next guy will ask "Why this all zero fake signature? Doesn't make sense to me!"

kosilin commented 2 years ago

))))) Proper comments will save you from unwanted questions.

[upd] I doesn't insist. I understand that it's your project, your code. I just hope that I can suggest something useful. )