debugWIRE via USB UART

Go To Last Post
70 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

https://github.com/dcwbrown/dwire-debug

Simple stand-alone debugger for ATtiny 45 and other DebugWIRE chips connected directly to an FT232R or similar on Linux or Windows.

...

GPLv2

Windows 8.1 plus Cygwin and MinGW, Ubuntu 15.04

USB UARTs are FT232R and CH340; CP210x is non-functional with PL2303 as unknown TBD.

(PL2303 in http://www.avrfreaks.net/forum/debugwire-usb-uart#comment-2279346)

 

Edit : PL2303

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Mon. Sep 25, 2017 - 07:51 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

found via

[Avr-ada-devel] programmer / debugger.

https://sourceforge.net/p/avr-ada/mailman/message/36028382/

...

I use it on a attiny441. It is quite liberal, as long as there is a dwire facility on the chip.

...

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cool stuff!

Might work out better than the current ICE/AVaRICE setup.

Thank you for the tip!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

canbeany1 wrote:
Cool stuff!
Indeed

8-pin tiny85 are very popular so having program and debug on one pin is an advantage.

Could consider replacing tiny85 (debugWIRE, DIP, SOIC, QFN) with tiny814 or tiny817 (UPDI, SOIC-14, QFN) and program over UPDI via a USB UART.

canbeany1 wrote:
Might work out better than the current ICE/AVaRICE setup.
Yes since mEDBG is not available as an orderable part.

Advantage AVaRICE since that's an AVR GDB server; dwire-debug has an issue to finish its AVR GDB server.

 


http://www.microchip.com/wwwproducts/en/attiny85

http://platformio.org/boards?count=1000&filter%5Bmcu%5D=ATTINY&filter%5Bplatform%5D=atmelavr&page=1&sorting%5Bname%5D=asc

http://www.microchip.com/wwwproducts/en/attiny814

http://www.microchip.com/wwwproducts/en/attiny817

http://www.avrfreaks.net/forum/cant-figure-out-how-program-attiny817#comment-2034271

http://avarice.sourceforge.net/

Integrate amazing GDB mode from @kadamski #13

https://github.com/dcwbrown/dwire-debug/issues/13

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Anyone tried a CH340 USB/UART with this yet?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've downloaded and built the package, but I haven't wired up a diode yet.  Won't get to my shop until sometime this week.  But I'm eager to try it.

 

Don't have a CH340, both my converters are FT232.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's pretty neat...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gchapman wrote:

Yes since mEDBG is not available as an orderable part.

Advantage AVaRICE since that's an AVR GDB server; dwire-debug has an issue to finish its AVR GDB server

 

dwire-debug GDB works better than AVaRICE + Atmel ICE. FINALLY it stops by itself on breakpoints, no need to watch the activity led on the ICE and hitting CTRL + c.

 

Ashlyn Black wrote:

Anyone tried a CH340 USB/UART with this yet?

 

From ReadMe.md:

CH340 based adapters have also been tested successfully on Linux and Windows
using tha standard OS drives. (Thanks to @a-v-s and @kadamski).

However CP210x based UARTs don't support Windows/Linux APIs for selecting custom baud
rates and I haven't had any success with them. Nor have the PL2303 based UARTS I
have tried worked for any purpose - I don't know if a good PL2303 would work.

I have a working debugger using an el-cheapo pl2303 on Debian Stretch though.

This is nothing short of amazing.. If you see this, thank you developers!

 

Flashing via DW also works like a charm, which was not supported by AVaRICE + ICE.

Last Edited: Mon. Sep 25, 2017 - 08:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Very interesting! But, Uh! What I don't have handy right now is that darn diode..

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

JohanEkdahl wrote:

Very interesting! But, Uh! What I don't have handy right now is that darn diode..

 

I didn't see any diode specs, so I guess "everything" works.

Just chiming in to tell I used a Chinese 0.01$ 1N4148 + 1.25$ pl2303 and some dupont cable.

Cheapest programmer/debugger ever!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I expect a diode with a low VF will be a good choice, especially at lower VCC.  But then again, it's not clear from any of the literature whether or not the DW hardware on the target is bound by the same VIH/VIL thresholds by which GPIO are bound, so it really may not make much difference.  Perhaps DW uses VRST?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I have my first problem. It hits a breakpoint every time after finishing main, even though there isn't one there.

 

Unconnected.                            > l /home/a/base/blink/Debug/blink.elf
ttyUSB1 .........
Connected to DebugWIRE device on USB serial port ttyUSB1 at baud rate 123825
Device recognised as ATmega328P
Loading 1038 flash bytes from ELF text segment 0 to addresses $0 through $40d.
                    0000: 940c  jmp   $00$0034              > g
Device reached breakpoint.                                        
main.c[27]          0110: 9598  break                       > 

 

dwire-debug says this is at 0x110:
main.c[27]          0110: 9598  break                       > p 0x110

disassembly says:
110:	cb cf       	rjmp	.-106    	; 0xa8 <main+0x18>

It worked fine in the beginning, don't know what made this happen.

 

GDB:

Program stopped.
main () at ../main.c:27
27		}
Device reached breakpoint.                                        
Got: g
Got: m90,27
Got: mb7,19
Got: qL1160000000000000000

 

Issuing a "jump *0x8a" gets it back, blinks the led after 0.5 sec and stops at  } again.

Given it enough time for today, will start looking at sources of dwire-debug tomorrow.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Given it enough time for today, will start looking at sources of dwire-debug tomorrow.

I took a brief look yesterday, and was dismayed at all the #include "foo.c" ...

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

canbeany1 wrote:
dwire-debug GDB works better than AVaRICE + Atmel ICE.
Thanks for the confirmation.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Likely any small signal or small switching diode.

Sources are any malfunctioning electronics on through-hole PCB (VCR, TV, old radio, microwave oven)

Consumer electronics is a low margin operation (single layer PCB, wave solder)

A power diode (rectifier) might be acceptable.

 

Radio Shack ... oh

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I expect a diode with a low VF will be a good choice, ...
or low junction capacitance.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

canbeany1 wrote:
It worked fine in the beginning, don't know what made this happen.
Possible lack of initialization.

Try exit all and restart the shell.

Also, could be the debugWIRE address comparator is not being disabled or reset.

canbeany1 wrote:
... will start looking at sources of dwire-debug tomorrow.
May your code review bear fruit.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

or low junction capacitance.

Good point.  A low-VF diode like the 1N5817 has a typical capacitance of 110pF, quite a bit higher than that of the 1N4001, 15 pF.

 

At 125000 kbps, bit time would be 8 us.  The pull-up on /RESET is in the neighbourhood of 60K worst case.  So for the 1N4001 the TC of the rising edge of DW would be 900ns.  Compared to a bit time of 8000ns, not really an issue.  By the centre of a bit slot (where a sample would be made), the voltage would be at 98.8% of VCC, well above VIH.

 

For the 1N5817, a TC of 6.6us means mid-bit represents only 54.5% of VIH.  Not good.

 

A 1N4148 has a max junction capacitance of 4pF, so better.

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Flashing via DW also works like a charm,

Does it do fuses and EEPROM?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I hooked up a 1N4148 and I'm in business with a t85.

It worked fine in the beginning, don't know what made this happen.

Peculiar.  Hasn't happened to me.  So you're saying the breakpoint you previously set survives a restart of dwdebug?  Have you tried clearing the breakpoint with the bc command?

 

I have other issues.  First, the elf would load correctly.  Built blinky with 3.5.4 (4.9.2), built dwdebug on Ubuntu 10.04LTS stock repo gcc et al.  Loading elf would fail in an interesting way.  If, say, the first instruction word to load were 0xC00E, what got loaded was 0x0E0E.  That is, the MSByte was replaced by a copy of the LSByte.  This problem happens for every word of flash programmed.  It is not an artefact of the f command which displays flash contents.  Popping the t85 back into my programmer, disabling DWEN (via HVSP), and reading flash confirms this strange LSB-to-MSB mirroring.  Obviously, the code runs amok.

 

Building (and running) dwdebug under Ubuntu 16.04 stock repo gcc solves the problem, even with the AVR .elf loaded, so the problem isn't with the .elf generated under 10.04.  Running the 10.04-built dwdebug under 16.04 shows the same byte-mirroring problem, so the issue is in the executable as built under 10.04.  A brief look at the source code made me gasp, as the author makes liberal use of the 'no-no' of #including .c files.  God knows what other silly things have been done.

 

More critically, the data dump and register dump seem to be inaccurate, at times wildly so.  I'll look into it some more at a later time.  Pooped, going to bed.

 

Does it do fuses and EEPROM?

Doesn't seem to.

 

Also, I haven't tried gdb/ddd yet.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Does it do fuses and EEPROM?

Doesn't seem to.

And no lock bits I guess, DW was meant for debugging and NOT programming.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like the reverse engineering leg work (here) includes EEPROM, but not fuses or lock bits.  The tool itself doesn't seem to support EEPROM.  No biggie either way, I've got a programmer.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

So the peculiar behaviour I mentioned in #20 seems to be limited to r29, r30, and r31.  When single-stepping or breaking, the contents those register seems to spontaneously change.

 

Starting from a virgin chip, which has seen VCC=0, so flash contents is all 0xFF and GP reg contents are 'random':

$ dwdebug reset,f,r,q
ttyUSB0 .............
Connected to DebugWIRE device on USB serial port ttyUSB0 at baud rate 7839
Device recognised as ATtiny85
0000:   ff ff ff ff  ff ff ff ff   ff ff ff ff  ff ff ff ff   ................
0010:   ff ff ff ff  ff ff ff ff   ff ff ff ff  ff ff ff ff   ................
0020:   ff ff ff ff  ff ff ff ff   ff ff ff ff  ff ff ff ff   ................
0030:   ff ff ff ff  ff ff ff ff   ff ff ff ff  ff ff ff ff   ................
0040:   ff ff ff ff  ff ff ff ff   ff ff ff ff  ff ff ff ff   ................
0050:   ff ff ff ff  ff ff ff ff   ff ff ff ff  ff ff ff ff   ................
0060:   ff ff ff ff  ff ff ff ff   ff ff ff ff  ff ff ff ff   ................
0070:   ff ff ff ff  ff ff ff ff   ff ff ff ff  ff ff ff ff   ................
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:81   r17:01   r18:04   r19:00   r20:28   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:b0   r28:12   r29:ff   r30:a6   r31:08
SREG:--------     ---------X:b006   ---------Y:ff12   ---------Z:08a6
SP:025f
PC:0000

NOTE:  I've edited the source of dwdebug a bit to alter the presentation of the 'r' command, but rest assured the issue doesn't lie with my modifications.  It was present before.

 

Now a simple test program:

$ cat dwdebug_test.S
#define __SFR_OFFSET 0
#include <avr/io.h>

.section .text

; Main.
.global main
main:
        ldi     r28, 0x55
        ldi     r29, 0xAA
        movw    r30, r28
loop:
        rjmp    loop

Build and debug:

$ avr-gcc -nostartfiles -mmcu=attiny85 dwdebug_test.S -o dwdebug_test.elf
$ dwdebug l dwdebug_test.elf,u,reset,r
ttyUSB0 .............
Connected to DebugWIRE device on USB serial port ttyUSB0 at baud rate 7839
Device recognised as ATtiny85
Loading 8 flash bytes from ELF text segment 0 to addresses $0 through $7.
0000: e5c5  ldi   r28, $55
0002: eada  ldi   r29, $aa
0004: 01fe  movw  r31:r30,r29:r28

loop:
0006: cfff  rjmp  loop (+0)
0008: ffff
000a: ffff
000c: ffff
000e: ffff
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:81   r17:01   r18:04   r19:00   r20:28   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:b0   r28:12   r29:ff   r30:20   r31:00
SREG:--------     ---------X:b006   ---------Y:ff12   ---------Z:0020
SP:025f
PC:0000
0000: e5c5  ldi   r28, $55              >

So far so good.  Same 'random' contents as for the virgin device, so no code has run yet (as expected).

 

Now we set a BP on loop, then go and examine registers:

0000: e5c5  ldi   r28, $55              > b 6
0000: e5c5  ldi   r28, $55              > g
Device reached breakpoint.                                        

loop:
0006: cfff  rjmp  loop (+0)             > r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:06
r16:81   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:ff   r30:55   r31:aa
SREG:--------     ---------X:a006   ---------Y:ff55   ---------Z:aa55
SP:025f
PC:0006

loop:
0006: cfff  rjmp  loop (+0)             >

Hmm.  r28 contains the correct value of 0x55, but r29 should have 0xAA.  Instead it has 0xFF.

 

I then wipe the chip, ensure VCC drop to 0, and start again, but this time single-stepping all the way.

 

First load .elf and report registers:

$ dwdebug l dwdebug_test.elf,u,reset,r
ttyUSB0 .............
Connected to DebugWIRE device on USB serial port ttyUSB0 at baud rate 7839
Device recognised as ATtiny85
Loading 8 flash bytes from ELF text segment 0 to addresses $0 through $7.
0000: e5c5  ldi   r28, $55
0002: eada  ldi   r29, $aa
0004: 01fe  movw  r31:r30,r29:r28

loop:
0006: cfff  rjmp  loop (+0)
0008: ffff
000a: ffff
000c: ffff
000e: ffff
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:12   r29:ff   r30:20   r31:00
SREG:--------     ---------X:a006   ---------Y:ff12   ---------Z:0020
SP:025f
PC:0000
0000: e5c5  ldi   r28, $55              >

... same 'random' contents as before.  Good.

 

Now one step:

0000: e5c5  ldi   r28, $55              > t,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:ea   r30:20   r31:00
SREG:--------     ---------X:a006   ---------Y:ea55   ---------Z:0020
SP:025f
PC:0002
0002: eada  ldi   r29, $aa              >

Well, r28 contains 0x55 as it should, but r29 has also changed.  It was 0xFF, but now it has spontaneously changed to 0xEA.

 

That's funny, the MSByte of the instruction at which we've stopped (i.e. will execute next) is also 0xEA.  I wonder...

 

Another step

0002: eada  ldi   r29, $aa              > t,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:aa   r30:20   r31:00
SREG:--------     ---------X:a006   ---------Y:aa55   ---------Z:0020
SP:025f
PC:0004
0004: 01fe  movw  r31:r30,r29:r28       >

Rats.  r29 should have been loaded with 0xAA, and so it has.  So that theory is at least incomplete.

 

A third step:

0004: 01fe  movw  r31:r30,r29:r28       > t,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:cf   r30:55   r31:cf 
SREG:--------     ---------X:a006   ---------Y:cf55   ---------Z:cf55
SP:025f
PC:0006

loop:
0006: cfff  rjmp  loop (+0)             >

Well, well.  So r29 has changed spontaneously again.  It should still be 0xAA, but is now 0xCF.  Incidentally, that's (again) the same value as the MSByte of the next instruction.

 

What's more, the instruction we just stepped through should have copied r29:r28 into r31:r30.  It did, but r31 has taken on the incorrect, spontaneously changed value of r29, not the correct value of 0xAA which it once held.

 

One more step:

0006: cfff  rjmp  loop (+0)             > t,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:ff   r30:55   r31:cf 
SREG:--------     ---------X:a006   ---------Y:ff55   ---------Z:cf55
SP:025f
PC:0006

loop:
0006: cfff  rjmp  loop (+0)             >

Note how r29 has changed again, now containing 0xFF.  Although it's not shown, that is of course the MSByte of the next instruction in flash, since it remains unprogrammed (all 0xFFFF).  r28, r30, and r31 remain unchanged.

 

Now we repeat the single-step exercise above, but we display the registers twice after each step.  Also, instead of wiping the chip and dropping VCC to 0, I simply reset the device from the dwdebug session:

0006: cfff  rjmp  loop (+0)             > reset,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:ea   r30:0a   r31:00 
SREG:--------     ---------X:a006   ---------Y:ea55   ---------Z:000a
SP:025f
PC:0000
0000: e5c5  ldi   r28, $55              >

Wow.  Now r29, r30, and r31 are all changed.  The change to r30 and r31 seems to be the result of the reset command.

 

On with the test:

0000: e5c5  ldi   r28, $55              > t,r,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:ea   r30:0a   r31:00 
SREG:--------     ---------X:a006   ---------Y:ea55   ---------Z:000a
SP:025f
PC:0002
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:02   r30:0a   r31:00 
SREG:--------     ---------X:a006   ---------Y:0255   ---------Z:000a
SP:025f
PC:0002
0002: eada  ldi   r29, $aa              > t,r,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:aa   r30:0a   r31:00   <-- Note how r29 has the correct value here...
SREG:--------     ---------X:a006   ---------Y:aa55   ---------Z:000a
SP:025f
PC:0004
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:02   r30:0a   r31:00   <-- ... but it has spontaneously change here just by reading the registers.
SREG:--------     ---------X:a006   ---------Y:0255   ---------Z:000a
SP:025f
PC:0004
0004: 01fe  movw  r31:r30,r29:r28       > t,r,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:cf   r30:55   r31:cf 
SREG:--------     ---------X:a006   ---------Y:cf55   ---------Z:cf55
SP:025f
PC:0006
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:02   r30:55   r31:cf 
SREG:--------     ---------X:a006   ---------Y:0255   ---------Z:cf55
SP:025f
PC:0006

loop:
0006: cfff  rjmp  loop (+0)             > t,r,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:ff   r30:55   r31:cf   <-- Same here...
SREG:--------     ---------X:a006   ---------Y:ff55   ---------Z:cf55
SP:025f
PC:0006
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:02   r30:55   r31:cf   <-- ... and here.
SREG:--------     ---------X:a006   ---------Y:0255   ---------Z:cf55
SP:025f
PC:0006

loop:
0006: cfff  rjmp  loop (+0)             >

As commented in the code block above, the simple act of reading the registers is sufficient to alter the contents of r29.

 

One more test.  We single-step four times in a row to exercise all of the program's instructions, and only then query the registers:

0006: cfff  rjmp  loop (+0)             > reset,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:ff   r30:0a   r31:00 
SREG:--------     ---------X:a006   ---------Y:ff55   ---------Z:000a
SP:025f
PC:0000
0000: e5c5  ldi   r28, $55              > t,t,t,t,r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:aa   r30:55   r31:aa 
SREG:--------     ---------X:a006   ---------Y:aa55   ---------Z:aa55
SP:025f
PC:0006

loop:
0006: cfff  rjmp  loop (+0)             >

Now all is exactly as it should be.  Seems that the trace command for single-stepping isn't the cause of the problem, but the query registers command is.

 

One more register query confirms it:

0006: cfff  rjmp  loop (+0)             > r
 r0:00    r1:23    r2:30    r3:60    r4:04    r5:01    r6:10    r7:00
 r8:12    r9:19   r10:08   r11:11   r12:00   r13:20   r14:25   r15:04
r16:80   r17:01   r18:04   r19:00   r20:20   r21:c2   r22:06   r23:6c
r24:00   r25:02   r26:06   r27:a0   r28:55   r29:ff   r30:55   r31:aa 
SREG:--------     ---------X:a006   ---------Y:ff55   ---------Z:aa55
SP:025f
PC:0006

loop:
0006: cfff  rjmp  loop (+0)             >

Yup.

 

The implication is that break-points and/or the 'g' (Go) command, as well as the 'r' and 'reset' command appear to clobber at least three general purpose registers.

 

So now what?

 

Well, first I'd like to know if the problem is only in the copies of the registers cached within dwdebug itself, or if the targets actual registers are being affected.  The fact that r31 picked up the incorrect value after the movw instruction suggests that it is not a purely caching issue, but I know little about the debugWire protocol and how BP/SS is implemented.  I'd also like to know why r30 and r31 seem to be affected by the reset command.

 

More tests are likely to be revealing, but next I'll look at the source code for dwdebug to see if there's anything obvious.  A first glance shows that the three registers in question (r29, r30, and r31) appear to subject to special handling for several functions, so it's possible there are one or more bugs.  I don't know when I'll get around to it, so if someone else beats me to it, so much the better.  Perhaps I'll contact the author and point him to this thread.  If anyone else feels energised, they can point him here as well.

 

 

For the record, the changes I made to change the register presentation to my liking are below:

diff -rupN dwire-debug-master/src/commands/commands.c dwire-debug-master.patched/src/commands/commands.c
--- dwire-debug-master/src/commands/commands.c	2017-09-27 19:01:57.492384062 -0400
+++ dwire-debug-master.patched/src/commands/commands.c	2017-09-27 18:55:28.834042260 -0400
@@ -1,7 +1,7 @@
 #include "Disassemble.c"
 #include "DeviceCommand.c"
-#include "RegistersCommand.c"
 #include "StackCommand.c"
+#include "RegistersCommand.c"
 #include "UnassembleCommand.c"
 #include "Dump.c"
 #include "DumpCommand.c"
diff -rupN dwire-debug-master/src/commands/RegistersCommand.c dwire-debug-master.patched/src/commands/RegistersCommand.c
--- dwire-debug-master/src/commands/RegistersCommand.c	2017-09-27 19:01:57.388380205 -0400
+++ dwire-debug-master.patched/src/commands/RegistersCommand.c	2017-09-27 18:55:28.838042407 -0400
@@ -10,6 +10,7 @@ void DisplayAllRegisters() {
   buf[30] = R30;
   buf[31] = R31;

+#if 0
   for (int row=0; row<4; row++) {
     for (int column=0; column<8; column++) {
       if (column == 2  &&  row < 2) {Wc(' ');}
@@ -18,10 +19,19 @@ void DisplayAllRegisters() {
     }
     Wl();
   }
+#else
+  for (int reg=0; reg<32; reg++) {
+    if (reg < 10) {Wc(' ');}
+    Ws("r"); Wd(reg,1); Wc(':');
+    Wx(buf[reg],2); Ws("   ");
+    if ((reg % 8) == 7) Wl();
+  }
+#endif

   u8 io[3] = {0};  // SPL, SPH, SREG
   DwReadAddr(0x5D, sizeof(io), io);

+#if 0
   Ws("SREG ");
   for (int i=0; i<8; i++) {
     Wc((io[2] & (1<<(7-i))) ? "ITHSVNZC"[i] : "ithsvnzc"[i]); Wc(' ');
@@ -33,6 +43,20 @@ void DisplayAllRegisters() {
   Ws("Y ");   Wx(buf[29],2); Wx(buf[28],2); Ws("   ");
   Ws("Z ");   Wx(buf[31],2); Wx(buf[30],2); Ws("   ");
   Wl();
+#else
+  Ws("SREG:");
+  for (int i=0; i<8; i++) {
+    Wc((io[2] & (1<<(7-i))) ? "ITHSVNZC"[i] : '-');
+  }
+  Ws("     ");
+  Ws("---------X:");   Wx(buf[27],2); Wx(buf[26],2); Ws("   ");
+  Ws("---------Y:");   Wx(buf[29],2); Wx(buf[28],2); Ws("   ");
+  Ws("---------Z:");   Wx(buf[31],2); Wx(buf[30],2);
+  Wl();
+  StackCommand();
+  Ws("PC:");  Wx(PC,4);
+  Wl();
+#endif
 }

diff -rupN dwire-debug-master/src/commands/StackCommand.c dwire-debug-master.patched/src/commands/StackCommand.c
--- dwire-debug-master/src/commands/StackCommand.c	2017-09-27 19:01:57.400380650 -0400
+++ dwire-debug-master.patched/src/commands/StackCommand.c	2017-09-27 18:55:28.794040782 -0400
@@ -21,7 +21,7 @@ void StackCommand () {
     int addr = min(DataLimit(), ((sp[1] << 8) | sp[0]) + 1);
     int len  = min(DataLimit(), addr+16) - addr;

-    Ws("SP = "); Wx(addr-1,4);
+    Ws("SP:"); Wx(addr-1,4);

     if (len) {
       u8 buf[16];

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Sep 27, 2017 - 11:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the trial and the report.

joeymorin wrote:
... so if someone else beats me to it, so much the better.
Something instead of someone?

lint can identify the fruit that's on the ground.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lint can identify the fruit that's on the ground.

Have you taken a peek at the source?  I fear lint would haemorrhage from the ears, but by all means go for it.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

smiley

Haven't read the source code

Reason is have in stock only UPDI AVR or STK500 (mega8515 doesn't have debug)

Hope you and other ones have a good go at it as this has appeal ...

Cheapest programmer/debugger ever! - canbeany1

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

TL;DR:  I believe I've identified the problem, but haven't yet created a fix /TL;DR

 

I used strace to see what dwdebug was sending and receiving to the target over dW, and I'm fairly certain the issue is that r29 is implicated in (at least) the flash read instructions, probably other debug operations as well.  However, there seems to be no effort to preserve the contents of r29 before performing a flash read (although r29 is clearly employed during flash erase/write operations), so it gets clobbered.

 

In addition, r30 and r31 are preserved and cached before most instructions, as it seems Z is used by the dW OCD as an index register for read/write in much the same way spm/lpm use it, but they are not correctly restored when they should be, so they too are getting clobbered.

 

There is some support for this in the reverse-engineering leg work which underpins the endeavour.  The author has:

An explanation for C2

I think that there are instructions implemented in hardware.

.

.

.

------------------------------------------------

C2 02

0000: lpm r?,Z+
0001: out DWDR,r?

C2 02 -> 0 1 0 1 0 1...

 

... and earlier:

Reading a Flash Page

66 D0 00 1E D1 00 20 C2 05 20 ll hh D0 00 00 C2 02 D1 01 00 20 --128 bytes--

66
D0 00 1E D1 00 20 C2 05 20 ll hh -- Z = hhll

D0 00 00
C2 02 -- Read Flash
D1 01 00
20 -- GO, start reading.
--128 bytes from target--

0000: lpm r?,Z+
0001: out DWDR,r?

 

So it seems the author suspects that a register on the target is used by the OCD to perform the read of flash via the equivalent of an lpm instruction, then that register is sent back to the debugger via dW(/RESET) via the equivalent of a write to DWDR.

 

I captured the datastream over dW for a reset:

$ mkfifo foo
$ strace -xx dwdebug device ttyUSB0 7750 2> foo

... and in another window:

$ cat foo

 

The strace output reveals the following conversation, which I have annotated based on the reverse engineering leg work, but with changes based on my new understanding:

1st exchange
------------

// Fetch PC i.e. address of current (i.e. next to execute) instruction.
dwdebug:
  0xf0            // Get the PC. TAKE NOTE after a break this will return PC+1.
target:
  0x00            // Target says PC is 0006.
  0x06            // This is a word address, and is really PC+1 word as noted
                  // so actual byte address is (6-1)*2 = 10 = 0x000A.

 

2nd exchange
------------

// Fetch contents of Z (for preservation).
dwdebug:
  0x66            // Used before Reading/Writing memory.
  0xd0 0x00 0x1e  // Set the start address/register (r30).
  0xd1 0x00 0x20  // Set the end+1 address/register (r32).
  0xc2 0x01       // Read registers mode.
  0x20            // Execute.
target:
  0x55            // Target responds that r30 contains 0x55.
  0xaa            // Target responds that r31 contains 0xAA.
                  // This is expected, since the target was free-running the
                  // code shown below before the debug session started.

 

3rd exchange
------------

// Fetch target's dW ID
dwdebug:
  0xf3            // Report dW ID.
target:
  0x93            // Target says ...
  0x0b            // ... ATtiny85.

 

4th exchange
------------

// Read 4 bytes flash starting at PC of next instruction (for disassembly).
dwdebug:
  0x66            // Used before Reading/Writing memory.
  0xd0 0x00 0x1e  // Set the start address/register (r30).
  0xd1 0x00 0x20  // Set the end+1 address/register (r32).
  0xc2 0x05       // Write registers mode.
  0x20            // Execute.
  0x0a 0x00       // Z written to 0x000A (byte address of PC-1 fetched earlier).
  0xd0 0x00 0x00  // Set the start address/register (0x0000).
  0xd1 0x00 0x08  // Set the end+1 address/register (0x0008).
                  // This implies 8 bytes, but only 4 returned, so apparently
                  // need to set start/end based on 2x the desired number of
                  // bytes.  Dunno why.
  0xc2 0x02       // Read flash mode.
  0x20            // Execute.
target:
  0xff            // Target returns flash contents at 0x000A ...
  0xcf            // ...
  0xff            // ...
  0xff            // ... through 0x000E.
                  //
                  // To confirm, I'd previously loaded the following:
                  //
                  //   0:    c5 e5           ldi    r28, 0x55
                  //   2:    da ea           ldi    r29, 0xAA
                  //   4:    fe 01           movw    r30, r28
                  //   6:    0e 01           movw    r0, r28
                  //   8:    1f 01           movw    r2, r30
                  //   a:    ff cf           rjmp    .-2
                  //
                  // ... with the remainder of flash still 'virgin' 0xFF, so
                  // contents at:
                  //   c: ff ff
                  //
                  // This also explains why PC was 0x000A at start of dW
                  // session, since arget ran for a bit after power-up before
                  // starting dW session.
                  //
                  // Note that 4 bytes are fetch in case the instruction to be
                  // disassembled is a 2-word instruction.

 

// This is were we end up after starting dwdebug with the device command, which
// connects to the OCD and emits the disassembly of the instruction at the
// current PC at the dwdebug prompt.

 

5th exchange
------------

// Reset target, which was issued interactively at dwdebug prompt with 'reset'.
dwdebug:
  0x07            // Reset, this is followed by a break and 55.
target:
  0x00            // This is how the FT232 sees a break.
  0xff            // This is how the FT233 sees the mark after break.
  0x55            // Sync byte (used by debugger for auto-baud).

 

6th exchange
------------

// Fetch PC of current (i.e. next to execute) instruction.
dwdebug:
  0xf0            // Get the PC. TAKE NOTE after a break this will return PC+1.
target:
  0x00            // Target says PC is 0001
  0x01            // This is a word address, and is really PC+1 word as as so
                  // actual byte address is (1-1)*2 = 0 = 0x0000, (as expected
                  // after a reset).

 

7th exchange
------------

// Fetch contents of Z (for preservation).
dwdebug:
  0x66            // Used before Reading/Writing memory.
  0xd0 0x00 0x1e  // Set the start address/register (r30).
  0xd1 0x00 0x20  // Set the end+1 address/register (r32).
  0xc2 0x01       // Read registers mode.
  0x20            // Execute.
target:
  0x0e            // Target responds that r30 contains 0x0E
  0x00            // Target responds that r31 contains 0x00
                  // i.e. Z=0x000E
                  // This seems peculiar, because you might think that it
                  // should contain 0xAA55 since that's what the application
                  // code last did however, remember that Z was used as an
                  // index register in the 4th exchange above for reading
                  // flash.  It was written to 0x000A, and 4 bytes of flash
                  // were fetched:
                  //    0x000A
                  //    0x000B
                  //    0x000C
                  //    0x000D
                  // ... with a +1 post-increment of Z after each read, that
                  // left Z at:
                  //    0x000E
                  // IMO a proper debugger should always undo what it has
                  // done during the course of debugging.  The target device
                  // would not modify register contents after a reset, so the
                  // debugger should ensure the same.
                  
8th exchange
------------

// Read 4 bytes flash starting at PC of next instruction (for disassembly)
dwdebug:
  0x66            // Used before Reading/Writing memory.
  0xd0 0x00 0x1e  // Set the start address/register (r30).
  0xd1 0x00 0x20  // Set the end+1 address/register (r32).
  0xc2 0x05       // Write registers mode.
  0x20            // Execute.
  0x00 0x00       // Z written to 0x0000 (byte address of PC-1 fetched earlier)
  0xd0 0x00 0x00  // Set the start address/register (0x0000)
  0xd1 0x00 0x08  // Set the end+1 address/register (0x0008)
                  // This implies 8 bytes, but only 4 returned, so apparently
                  // need to set start/end based on 2x the desired number of
                  // bytes.
  0xc2 0x02       // Read flash mode.
  0x20            // Execute.
target:
  0xc5            // Target returns flash contents at 0x0000 ...
  0xe5            // ...
  0xda            // ...
  0xea            // ... through 0x0004
                  // This matches what I'd loaded into flash previously, see
                  // above.

 

9th exchange
------------

// Restores the previously preserved contents of Z, although that contents was
// itself a 'false' value that had not been properly preserved beforehand.
// Then exits debug session.  This exchange is as a result of the 'q' command
// at the dwdebug prompt.
dwdebug:
  0x66            // Used before Reading/Writing memory.
  0xd0 0x00 0x1e  // Set the start address/register (r30).
  0xd1 0x00 0x20  // Set the end+1 address/register (r32).
  0xc2 0x05       // Write registers mode.
  0x20            // Execute.
  0x0e 0x00       // Z written to 0x000E (incorrectly preserved value).
  0x60            // Used before a GO.
  0xd0 0x00 0x00  // Sets a start address to 0x0000 maybe?
  0x30            // GO (resume normal exection).
                  // It's unclear if this means that a debug session starts
                  // executing at 0x0000, or where the PC was left (in which
                  // case what is the 0xd0 0x00 0x00 for?).

 

// dwdebug exits

 

I've assembled a detailed log of another session, and it looks like a couple of things are missing from them:

  1. While Z (r31:30) is being preserved in many places, it is not being restored to the target after it is modified by a debug exchange.
  2. An unidentified register, by all appearances r29, is clobbered by the OCD as it replies to certain requests, apparently any time it returns the contents flash (and likely EEPROM, although not supported by dwdebug).

 

Below is an abridged log that I hope makes sense, based on the details given above.

 

First, the output of the session from which a assembled the log:

Connected to DebugWIRE device on USB serial port ttyUSB0 at baud rate 7750
Device recognised as ATtiny85
000a: cfff  rjmp  000a (+0)             > reset
0000: e5c5  ldi   r28, $55              > r
 r0:55    r1:aa    r2:55    r3:aa    r4:00    r5:00    r6:00    r7:00
 r8:00    r9:18   r10:00   r11:00   r12:00   r13:00   r14:00   r15:00
r16:00   r17:00   r18:00   r19:00   r20:00   r21:80   r22:02   r23:00
r24:00   r25:00   r26:00   r27:00   r28:55   r29:ea   r30:0e   r31:00
SREG:--------     ---------X:0000   ---------Y:ea55   ---------Z:000e
SP:025f
PC:0000
0000: e5c5  ldi   r28, $55              > t
0002: eada  ldi   r29, $aa              > r
 r0:55    r1:aa    r2:55    r3:aa    r4:00    r5:00    r6:00    r7:00
 r8:00    r9:18   r10:00   r11:00   r12:00   r13:00   r14:00   r15:00
r16:00   r17:00   r18:00   r19:00   r20:00   r21:80   r22:02   r23:00
r24:00   r25:00   r26:00   r27:00   r28:55   r29:01   r30:0e   r31:00
SREG:--------     ---------X:0000   ---------Y:0155   ---------Z:000e
SP:025f
PC:0002
0002: eada  ldi   r29, $aa              > t
0004: 01fe  movw  r31:r30,r29:r28       > r
 r0:55    r1:aa    r2:55    r3:aa    r4:00    r5:00    r6:00    r7:00
 r8:00    r9:18   r10:00   r11:00   r12:00   r13:00   r14:00   r15:00
r16:00   r17:00   r18:00   r19:00   r20:00   r21:80   r22:02   r23:00
r24:00   r25:00   r26:00   r27:00   r28:55   r29:01   r30:0e   r31:00
SREG:--------     ---------X:0000   ---------Y:0155   ---------Z:000e
SP:025f
PC:0004
0004: 01fe  movw  r31:r30,r29:r28       > t
0006: 010e  movw  r1:r0,r29:r28         > r
 r0:55    r1:aa    r2:55    r3:aa    r4:00    r5:00    r6:00    r7:00
 r8:00    r9:18   r10:00   r11:00   r12:00   r13:00   r14:00   r15:00
r16:00   r17:00   r18:00   r19:00   r20:00   r21:80   r22:02   r23:00
r24:00   r25:00   r26:00   r27:00   r28:55   r29:01   r30:55   r31:01
SREG:--------     ---------X:0000   ---------Y:0155   ---------Z:0155
SP:025f
PC:0006
0006: 010e  movw  r1:r0,r29:r28         > t
0008: 011f  movw  r3:r2,r31:r30         > r
 r0:55    r1:01    r2:55    r3:aa    r4:00    r5:00    r6:00    r7:00
 r8:00    r9:18   r10:00   r11:00   r12:00   r13:00   r14:00   r15:00
r16:00   r17:00   r18:00   r19:00   r20:00   r21:80   r22:02   r23:00
r24:00   r25:00   r26:00   r27:00   r28:55   r29:cf   r30:55   r31:01
SREG:--------     ---------X:0000   ---------Y:cf55   ---------Z:0155
SP:025f
PC:0008
0008: 011f  movw  r3:r2,r31:r30         > t
000a: cfff  rjmp  000a (+0)             > r
 r0:55    r1:01    r2:55    r3:01    r4:00    r5:00    r6:00    r7:00
 r8:00    r9:18   r10:00   r11:00   r12:00   r13:00   r14:00   r15:00
r16:00   r17:00   r18:00   r19:00   r20:00   r21:80   r22:02   r23:00
r24:00   r25:00   r26:00   r27:00   r28:55   r29:ff   r30:55   r31:01
SREG:--------     ---------X:0000   ---------Y:ff55   ---------Z:0155
SP:025f
PC:000a
000a: cfff  rjmp  000a (+0)             > t
000a: cfff  rjmp  000a (+0)             > r
 r0:55    r1:01    r2:55    r3:01    r4:00    r5:00    r6:00    r7:00
 r8:00    r9:18   r10:00   r11:00   r12:00   r13:00   r14:00   r15:00
r16:00   r17:00   r18:00   r19:00   r20:00   r21:80   r22:02   r23:00
r24:00   r25:00   r26:00   r27:00   r28:55   r29:ff   r30:55   r31:01
SREG:--------     ---------X:0000   ---------Y:ff55   ---------Z:0155
SP:025f
PC:000a
000a: cfff  rjmp  000a (+0)             > q

Now the log with comments on what's actually going on:

// All target data shown in order of receipt, which is LSB first.
 
// dwdebug is launched and connection established to target OCD.
 
// #01: Fetch PC.
dwdebug:
  0xf0
target:
  0x00 0x06 // Word address of PC+1.
 
// #02: Fetch Z (ostensibly to preserve it now and restore it later).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x01 0x20
target:
  0x55 0xaa
 
// #03: dW ID.
dwdebug:
  0xf3
target:
  0x93 0x0b
 
// #04: Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x0a 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xff 0xcf // a:  ff cf         rjmp  .-2
  0xff 0xff // c:  ff ff
 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 'reset' command.
 
// #05 Reset target.
dwdebug:
  0x07
target:
  0x00 0xff 0x55  // Break / MAB / sync.
 
// #06 Fetch PC.
dwdebug:
  0xf0
target:
  0x00 0x01 // Word address of PC+1.
 
// #07 Fetch Z (ostensibly to preserve it now and restore it later).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x01 0x20
target:
  0x0e 0x00 // This is value with which Z was clobbered in #04, because it was never restored to the value preserved in #02.
 
// #08 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x00 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xc5 0xe5 // 0:  c5 e5         ldi   r28, 0x55
  0xda 0xea // 2:  da ea         ldi   r29, 0xAA
 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 'r' command.
 
// #09 Read GP registers r0 through r29.  Note that dwdebug reports the cached
// values for r30 and r31 acquired by the last fetch of Z.

dwdebug:
  0x66
        0xd0 0x00 0x00 0xd1 0x00 0x1e 0xc2 0x01 0x20
target:
  0x55 0xaa 0x55 0xaa 0x00 0x00 0x00 0x00
  0x00 0x18 0x00 0x00 0x00 0x00 0x00 0x00
  0x00 0x00 0x00 0x00 0x00 0x80 0x02 0x00
  0x00 0x00 0x00 0x00 0x55 0xea // r29 contains the last byte returned by OCD in #08.
 

// #10 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5F, i.e.
// SPL, SPH, and SREG.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x06 0xc2 0x00 0x20
target:
  0x5f 0x02 0x00  // SP=025F  SREG:--------
 
// #11 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5D, i.e.
// SPL, SPH.  I wonder why dwdebug reads SPH:L twice?

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x04 0xc2 0x00 0x20
target:
  0x5f 0x02 // SP=025F
 
// #12 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x00 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xc5 0xe5 // 0:  c5 e5         ldi   r28, 0x55
  0xda 0xea // 2:  da ea         ldi   r29, 0xAA
 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 't' command.
 
// #13 Restore preserved value of Z, which wouldn't be needed if it were preserved immediately after the last exchange.
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x0e 0x00  // Z gets restored.
 
// #14 Single-step at PC=0x0000 (word).
dwdebug:
  0x60
        0xd0 0x00 0x00 0x31
target:
  0x00 0x55 // Break / Sync
 
// dwdebug stops at interactive prompt, user issues 'r' command.
 
// #15 Fetch PC.
dwdebug:
  0xf0
target:
  0x00 0x02 // Word address of PC+1.
 
// #16 Fetch Z (ostensibly to preserve it now and restore it later).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x01 0x20
target:
  0x0e 0x00 // This is value with which Z was clobbered in #11, because it was never restored to the value preserved in #07.
 
// #17 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x02 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xda 0xea // 2:  da ea         ldi   r29, 0xAA
  0xfe 0x01 // 4:  fe 01         movw  r30, r28
 
// #18 Read GP registers r0 through r29.  Note that dwdebug reports the cached
// values for r30 and r31 acquired by the last fetch of Z.

dwdebug:
  0x66
        0xd0 0x00 0x00 0xd1 0x00 0x1e 0xc2 0x01 0x20
target:
  0x55 0xaa 0x55 0xaa 0x00 0x00 0x00 0x00
  0x00 0x18 0x00 0x00 0x00 0x00 0x00 0x00
  0x00 0x00 0x00 0x00 0x00 0x80 0x02 0x00
  0x00 0x00 0x00 0x00 0x55 0x01 // r29 contains the last byte returned by OCD in #17.

 

// #19 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5F, i.e.
// SPL, SPH, and SREG.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x06 0xc2 0x00 0x20
target:
  0x5f 0x02 0x00  // SP=025F  SREG:--------
 
// #20 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5D, i.e.
// SPL, SPH.  I wonder why dwdebug reads SPH:L twice?

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x04 0xc2 0x00 0x20
target:
  0x5f 0x02 // SP=025F
 
// #21 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x02 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xda 0xea // 2:  da ea         ldi   r29, 0xAA
  0xfe 0x01 // 4:  fe 01         movw  r30, r28
 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 't' command.
 
// #22 Restore preserved value of Z, which wouldn't be needed if it were preserved immediately after the last exchange.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x0e 0x00  // Z gets restored.
 
// #23 Single-step at PC=0x0001 (word).
dwdebug:
  0x60
        0xd0 0x00 0x01 0x31
target:
  0x00 0x55 // Break / Sync
 
// #24 Fetch PC.
dwdebug:
  0xf0
target:
  0x00 0x03 // Word address of PC+1.
 
// #25 Fetch Z (ostensibly to preserve it now and restore it later).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x01 0x20
target:
  0x0e 0x00
 
// #26 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x04 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xfe 0x01 // 4:  fe 01         movw  r30, r28
  0x0e 0x01 // 6:  0e 01         movw  r0, r28

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 'r' command.
 

// #27 Read GP registers r0 through r29.  Note that dwdebug reports the cached
// values for r30 and r31 acquired by the last fetch of Z.

dwdebug:
  0x66
        0xd0 0x00 0x00 0xd1 0x00 0x1e 0xc2 0x01 0x20
target:
  0x55 0xaa 0x55 0xaa 0x00 0x00 0x00 0x00
  0x00 0x18 0x00 0x00 0x00 0x00 0x00 0x00
  0x00 0x00 0x00 0x00 0x00 0x80 0x02 0x00
  0x00 0x00 0x00 0x00 0x55 0x01 // r29 contains the last byte returned by OCD in #26.
 
// #28 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5F, i.e.
// SPL, SPH, and SREG.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x06 0xc2 0x00 0x20
target:
  0x5f 0x02 0x00  // SP=025F  SREG:--------
 
// #29 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5D, i.e.
// SPL, SPH.  I wonder why dwdebug reads SPH:L twice?

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x04 0xc2 0x00 0x20
target:
  0x5f 0x02 // SP=025F
 
// #30 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x04 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xfe 0x01 // 4:  fe 01         movw  r30, r28
  0x0e 0x01 // 6:  0e 01         movw  r0, r28

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 't' command.
 
// #31 Restore preserved value of Z, which wouldn't be needed if it were preserved immediately after the last exchange.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x0e 0x00  // Z gets restored.
 
// #32 Single-step at PC=0x0002 (word).
dwdebug:
  0x60
        0xd0 0x00 0x02 0x31
target:
  0x00 0x55 // Break / Sync
 
// #33 Fetch PC.
dwdebug:
  0xf0
target:
  0x00 0x04 // Word address of PC+1.
 
// #34 Fetch Z (ostensibly to preserve it now and restore it later).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x01 0x20
target:
  0x55 0x01
 
// #35 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x06 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:

  0x0e 0x01 // 6:  0e 01         movw  r0, r28
  0x1f 0x01 // 8:  1f 01         movw  r2, r30

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 'r' command.
 
// #36 Read GP registers r0 through r29.  Note that dwdebug reports the cached
// values for r30 and r31 acquired by the last fetch of Z.

dwdebug:
  0x66
        0xd0 0x00 0x00 0xd1 0x00 0x1e 0xc2 0x01 0x20
target:
  0x55 0xaa 0x55 0xaa 0x00 0x00 0x00 0x00
  0x00 0x18 0x00 0x00 0x00 0x00 0x00 0x00
  0x00 0x00 0x00 0x00 0x00 0x80 0x02 0x00
  0x00 0x00 0x00 0x00 0x55 0x01 // r29 contains the last byte returned by OCD in #35.
 
// #37 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5F, i.e.
// SPL, SPH, and SREG.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x06 0xc2 0x00 0x20
target:
  0x5f 0x02 0x00  // SP=025F  SREG:--------
 
// #38 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5D, i.e.
// SPL, SPH.  I wonder why dwdebug reads SPH:L twice?

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x04 0xc2 0x00 0x20
target:
  0x5f 0x02 // SP=025F
 
// #39 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x06 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0x0e 0x01 // 6:  0e 01         movw  r0, r28
  0x1f 0x01 // 8:  1f 01         movw  r2, r30

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 't' command.
 
// #40 Restore preserved value of Z, which wouldn't be needed if it were preserved immediately after the last exchange.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x55 0x01  // Z gets restored.
 
// #41 Single-step at PC=0x0003 (word).
dwdebug:
  0x60
        0xd0 0x00 0x03 0x31
target:
  0x00 0xff 0x55  // break/sync
 
// #42 Fetch PC.
dwdebug:
  0xf0
target:
  0x00 0x05 // Word address of PC+1.
 
// #43 Fetch Z (ostensibly to preserve it now and restore it later).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x01 0x20
target:
  0x55 0x01
 
// #44 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x08 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xff 0xcf // a:  ff cf         rjmp  .-2
  0xff 0xff // c:  ff ff

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 'r' command.
 
// #45 Read GP registers r0 through r29.  Note that dwdebug reports the cached
// values for r30 and r31 acquired by the last fetch of Z.

dwdebug:
  0x66
        0xd0 0x00 0x00 0xd1 0x00 0x1e 0xc2 0x01 0x20
target:
  0x55 0x01 0x55 0xaa 0x00 0x00 0x00 0x00
  0x00 0x18 0x00 0x00 0x00 0x00 0x00 0x00
  0x00 0x00 0x00 0x00 0x00 0x80 0x02 0x00
  0x00 0x00 0x00 0x00 0x55 0xcf // r29 contains the last byte returned by OCD in #44.
 
// #46 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5F, i.e.
// SPL, SPH, and SREG.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x06 0xc2 0x00 0x20
target:
  0x5f 0x02 0x00  // SP=025F  SREG:--------
 
// #47 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5D, i.e.
// SPL, SPH.  I wonder why dwdebug reads SPH:L twice?

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x04 0xc2 0x00 0x20
target:
  0x5f 0x02 // SP=025F
 
// #48 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x08 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xff 0xcf // a:  ff cf         rjmp  .-2
  0xff 0xff // c:  ff ff

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 't' command.
 
// #49 Restore preserved value of Z, which wouldn't be needed if it were preserved immediately after the last exchange.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x55 0x01  // Z gets restored.
 
// #50 Single-step at PC=0x0004 (word).
dwdebug:
  0x60
        0xd0 0x00 0x04 0x31
target:
  0x00 0xff 0x55  // break/sync
 
// #51 Fetch PC.
dwdebug:
  0xf0
target:
  0x00 0x06 // Word address of PC+1.
 
// #52 Fetch Z (ostensibly to preserve it now and restore it later).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x01 0x20
target:
  0x55 0x01
 
// #53 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x0a 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xff 0xcf // a:  ff cf         rjmp  .-2
  0xff 0xff // c:  ff ff

 

// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 'r' command.
 
// #54 Read GP registers r0 through r29.  Note that dwdebug reports the cached
// values for r30 and r31 acquired by the last fetch of Z.

dwdebug:
  0x66
        0xd0 0x00 0x00 0xd1 0x00 0x1e 0xc2 0x01 0x20
target:
  0x55 0x01 0x55 0x01 0x00 0x00 0x00 0x00
  0x00 0x18 0x00 0x00 0x00 0x00 0x00 0x00
  0x00 0x00 0x00 0x00 0x00 0x80 0x02 0x00
  0x00 0x00 0x00 0x00 0x55 0xff // r29 contains the last byte returned by OCD in #53.
 
// #55 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5F, i.e.
// SPL, SPH, and SREG.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x06 0xc2 0x00 0x20
target:
  0x5f 0x02 0x00  // SP=025F  SREG:--------
 
// #56 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5D, i.e.
// SPL, SPH.  I wonder why dwdebug reads SPH:L twice?

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x04 0xc2 0x00 0x20
target:
  0x5f 0x02 // SP=025F
 
// #57 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x0a 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xff 0xcf // a:  ff cf         rjmp  .-2
  0xff 0xff // c:  ff ff

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 't' command.
 
// #58 Restore preserved value of Z, which wouldn't be needed if it were preserved immediately after the last exchange.

dwde6ug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x55 0x01  // Z gets restored.
 
// #59 Single-step at PC=0x0005 (word).
dwdebug:
  0x60
        0xd0 0x00 0x05 0x31
target:
  0x00 0x55 // Break / Sync
 
// #60 Fetch PC.
dwdebug:
  0xf0
target:
  0x00 0x06 // Word address of PC+1.
 
// #61 Fetch Z (ostensibly to preserve it now and restore it later).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x01 0x20
target:
  0x55 0x01
 
// #62 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x0a 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xff 0xcf // a:  ff cf         rjmp  .-2
  0xff 0xff // c:  ff ff

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 'r' command.
 
// #63 Read GP registers r0 through r29.  Note that dwdebug reports the cached
// values for r30 and r31 acquired by the last fetch of Z.

dwdebug:
  0x66
        0xd0 0x00 0x00 0xd1 0x00 0x1e 0xc2 0x01 0x20
target:
  0x55 0x01 0x55 0x01 0x00 0x00 0x00 0x00
  0x00 0x18 0x00 0x00 0x00 0x00 0x00 0x00
  0x00 0x00 0x00 0x00 0x00 0x80 0x02 0x00
  0x00 0x00 0x00 0x00 0x55 0xff // r29 contains the last byte returned by OCD in #62.
 
// #64 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5F, i.e.
// SPL, SPH, and SREG.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x06 0xc2 0x00 0x20
target:
  0x5f 0x02 0x00  // SP=025F  SREG:--------
 
// #65 Read SRAM-mapped I/O registers at addresses 0x5D through 0x5D, i.e.
// SPL, SPH.  I wonder why dwdebug reads SPH:L twice?

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x5d 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x04 0xc2 0x00 0x20
target:
  0x5f 0x02 // SP=025F
 
// #66 Read flash (4 bytes).
dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x0a 0x00  // Z gets clobbered.
        0xd0 0x00 0x00 0xd1 0x00 0x08 0xc2 0x02 0x20
target:
  0xff 0xcf // a:  ff cf         rjmp  .-2
  0xff 0xff // c:  ff ff

 
// MISSING:  Z should have been restored here.
 
// dwdebug stops at interactive prompt, user issues 'q' command.
 
// #67 Restore preserved value of Z, which wouldn't be needed if it were preserved immediately after the last exchange.

dwdebug:
  0x66
        0xd0 0x00 0x1e 0xd1 0x00 0x20 0xc2 0x05 0x20 0x55 0x01  // Z gets restored
 
// #68 Resume at PC=0x0005 (word).
dwdebug:
  0x60
        0xd0 0x00 0x05 0x30

 

 

I have not investigated all of the other dwdebug commands, but I expect the problem is not limited to what I've shown here.

 

Incidentally, it looks like the primitive 0x0d is used to load the PC, and the PC is itself used as an index register of sorts for the other primitives which read/write memories (registers, SRAM, flash, and likely EEPROM).  When stepping or continuing, the PC must be explicitly set to the address of the instruction to execute.

 

r29 (and r31:30) is possibly clobbered by other operations as well.

 

The safest thing to do would seem to be to always preserve/restore r31:29, except for operations which definitively do not clobber them.

 

Ideally I should just be able to add a couple of lines of code to effect these changes.  I have yet to dig too deep into the source code for dwdebug.  I'm finding it to be a challenge, as it is fairly unstructured, makes use of a number of obfuscatory (if clever) macros, lacks consistency in the formatting of exchanged data literals, with a lot of inter-module dependencies.  The use of the word module isn't even especially appropriate, as the entire source code is compiled as a single translation unit, with all of the .c files #included through a series of #included #includes.  Not a single .h to be found.  Oy.

 

I may just poke at this with a stick some more to log more exchanges between dwdebug and the OCD, and then re-implement the whole thing from the ground up.  Dunno when.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Oct 1, 2017 - 06:21 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
I captured the datastream over dW for a reset:
Thanks for wasn't aware of named pipes.

joeymorin wrote:
The strace output reveals the following conversation, which I have annotated based on the reverse engineering leg work, but with changes based on my new understanding:
Wow ... Thanks for your effort!

joeymorin wrote:
... and then re-implement the whole thing from the ground up.
Won't be forking it cheeky

Sometimes taking on the challenge is the more common approach.

Been in bit similar circumstances though with a boss I didn't want to piss off by doing a rewrite.

joeymorin wrote:
Dunno when.
In a way, time is meaningless.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, there are five options, as I see it:

  1. submit changes
  2. submit rewrite
  3. rewrite as a fork
  4. rewrite and keep it to myself
  5. leave it

 

One requires greater effort to understand existing code.  Two and three have the potential to put noses out of joint.  Four: it's GPL 2.0, so permissible, but bad karma ;-)

 

Five is unsavoury, as currently dwdebug is my best option for debugging under Linux.  To be so close and walk away would be difficult.

 

I've captured strace dumps of short sessions covering all of dwdebug's commands.  I'll start by understanding where the current tool is falling down w.r.t. preservation/restoration of r31:29, and maybe I'll spend some time figuring out a clean patch to remedy that, and submit it for consideration.  However I think I'll still keep a re-write on the table.  I won't have a lot of time to throw at it for a while, though.  How I proceed w.r.t. the disposition of that rewrite will depend on how much time I'm able to chisel out in the coming months.

 

Thanks for your interest, and thanks for your OP!

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're welcome!

joeymorin wrote:
Well, there are five options, as I see it:
0. Create an issue (maybe the creator of dwire-debug will solve the issue or by one of the other (3) members)

joeymorin wrote:
Two and three have the potential to put noses out of joint.
... or not wink

Couldn't locate a dwire-debug issue that describes this specific problem.

I comprehend the r29 and Z issue per your findings post so I can create the issue.

I'll be able to follow and respond during the initial part of the issue's discussion; if necessary to continue then I'll procure a debugWIRE AVR for the STK500.

joeymorin wrote:
Four: it's GPL 2.0, so permissible, but bad karma ;-)
Disagree on karma as use of GPL code in proof-of-concept makes the first demonstration easier to accomplish.

Use of GPL in inside-the-fence products "may" be OK.

When the product has left the the gate then GPL use needs an evaluation.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

USB UARTs are ...

and tiny45 and tiny85 in the Little Wire branch :

LittleWire/DigiSpark branch

This branch is for the development of a version of dwire-debug that supports both FT232 and DigiSpark programmed with an extended version of LittleWire.

https://github.com/dcwbrown/dwire-debug/tree/lwire

 


Little Wire

https://littlewire.github.io/

Logo

Digistump

Digispark USB Development Board

http://digistump.com/products/1

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmmm, a lightweight debugger/programmer would be very nice. Something like DDT, or even better ZSID ('cos it had symbols).

 

This has been posted before...

 

https://github.com/N-Bz/pyupdi

 

...I don't know if it would work but they use just a resistor to combine the TX/RX onto a single pin.

 

 

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Another discovery.

 

Flash is not written under an ATmega328P.  The load operation proceeds without errors, but flash is not modified.

 

I expect flash will fail to be written to any device with a BLS and more than 8kB of flash.

 

The reason lies here:

Writing a Flash Page

66 D0 00 1A D1 00 20 C2 05 20 --03 01 05 40 00 00-- --Set XYZ--

D0 1F 00 -- Set PC to 0x1F00, inside the boot section to enable spm--
64
D2 01 CF 23 movw r24,r30
D2 BF A7 23 out SPMCSR,r26 = 03 = PGERS
D2 95 E8 33 spm
00 <55> 83 <55>

44 - before the first one
And then repeat the following until the page is full.

D0 1F 00 - set PC to bootsection for spm to work
D2 B6 01 23 ll - in r0,DWDR (ll)
D2 B6 11 23 hh - in r1,DWDR (hh)
D2 BF B7 23 - out SPMCSR,r27 = 01 = SPMEN
D2 95 E8 23 - spm
D2 96 32 23 - adiw Z,2

D0 1F 00
D2 01 FC 23 movw r30,r24
D2 BF C7 23 out SPMCSR,r28 = 05 = PGWRT
D2 95 E8 33 spm
00 <55>

D0 1F 00
D2 E1 C1 23 ldi r28,0x11
D2 BF C7 23 out SPMCSR,r28 = 11 = RWWSRE
D2 95 E8 33 spm
00 <55> 83 <55>

This works for a t85 because firstly there is no BLS, and spm works everywhere.  Secondly, it would likely work for an m88 because 0x1F00 >>is<< within the BLS.  However, it is not within the BLS for the 328P.

 

My captures of the dW line during a session with an m328P nevertheless show 0x1F00 is being sent.

 

A look at the source shows that this is in fact hard-coded... not once, but in three separate places.

 

What is lacking is a member in the 'Characteristics' LUT in GlobalData.c.  Currently, the table looks like this:

struct {
  int   signature;
  int   ioregSize;
  int   sramSize;
  int   eepromSize;
  int   flashSize;  // In bytes
  int   DWDR;       // DebugWIRE data register, aka MONDR - Monitor data register
  int   pageSize;   // In bytes
  char *name;
} Characteristics[] = {
//    sig   io  sram eeprom flash  dwdr   pg   name
  {0x9007,  64,   64,   64,  1024, 0x2E,  32, "ATtiny13"},

  {0x9108,  64,  128,  128,  2048, 0x22,  32, "ATtiny25"},
  {0x910B,  64,  128,  128,  2048, 0x27,  32, "ATtiny24"},

  {0x9205, 224,  512,  256,  4096, 0x31,  64, "ATmega48A"},
  {0x9206,  64,  256,  256,  4096, 0x22,  64, "ATtiny45"},
  {0x9207,  64,  256,  256,  4096, 0x27,  64, "ATtiny44"},
  {0x920A, 224,  512,  256,  4096, 0x31,  64, "ATmega48PA"},
  {0x9215, 224,  256,  256,  4096, 0x27,  16, "ATtiny441"},

  {0x930A, 224, 1024,  512,  8192, 0x31,  64, "ATmega88A"},
  {0x930B,  64,  512,  512,  8192, 0x22,  64, "ATtiny85"},
  {0x930C,  64,  512,  512,  8192, 0x27,  64, "ATtiny84"},
  {0x930F, 224, 1024,  512,  8192, 0x31,  64, "ATmega88PA"},
  {0x9315, 224,  512,  512,  8192, 0x27,  16, "ATtiny841"},
  {0x9389, 224,  512,  512,  8192, 0x31,  64, "ATmega8U2"},

  {0x9406, 224, 1024,  512, 16384, 0x31, 128, "ATmega168A"},
  {0x940B, 224, 1024,  512, 16384, 0x31, 128, "ATmega168PA"},
  {0x9489, 224,  512,  512, 16384, 0x31, 128, "ATmega16U2"},

  {0x950F, 224, 2048, 1024, 32768, 0x31, 128, "ATmega328P"},
  {0x9514, 224, 2048, 1024, 32768, 0x31, 128, "ATmega328"},
  {0x958A, 224, 1024, 1024, 32768, 0x31, 128, "ATmega32U2"},
  {0,      0,   0,    0,    0,     0,    0}
};

 

Knowledge of the BLS is needed:

struct {
  int   signature;
  int   ioregSize;
  int   sramSize;
  int   eepromSize;
  int   flashSize;  // In bytes
  int   DWDR;       // DebugWIRE data register, aka MONDR - Monitor data register
  int   pageSize;   // In bytes
  int   bls;        // In bytes
  char *name;
} Characteristics[] = {
//    sig   io  sram eeprom flash  dwdr   pg   bls   name
.
.
.
  {0x950F, 224, 2048, 1024, 32768, 0x31, 128, 0x7E00 "ATmega328P"},
.
.
.
  {0,      0,   0,    0,    0,     0,    0}
};

... and changes to the code to use it.

 

Or, perhaps better, code could compute the appropriate PC based on (Characteristics.flashSize[] - Characteristics[)device>].pageSize) and avoid an additional member.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Tue. Oct 3, 2017 - 04:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's a patch which addresses the issue in #33:

diff -rupN dwire-debug-master/src/commands/WriteFlash.c dwire-debug-master.patched/src/commands/WriteFlash.c
--- dwire-debug-master/src/commands/WriteFlash.c	2017-09-27 19:01:57.460382876 -0400
+++ dwire-debug-master.patched/src/commands/WriteFlash.c	2017-10-04 00:42:16.896732816 -0400
@@ -10,7 +10,7 @@ void EraseFlashPage(u16 a) { // a = byte
   DwWrite(ByteArrayLiteral(
     0x66, 0xD0, 0, 29, 0xD1, 0, 32,      // Set PC=29, BP=32 - address registers r29 through r31
     0xC2, 5, 0x20, PGERS, lo(a), hi(a),  // r29=op, Z=first byte address of page
-    0xD0, 0x1F, 0,                       // Set PC=$1F00, inside the boot section to enable spm
+    0xD0, hi(bls()), lo(bls()),          // Set PC inside the boot section to enable spm
     0x64, 0xD2, 0xBF, 0xD7, 0x23,        // out SPMCSR,r29 (3=PGERS, 5=PGWRT)
     0xD2, 0x95, 0xE8, 0x33               // spm
   ));
@@ -42,7 +42,7 @@ void ProgramFlashPage(u16 a, const u8 *b
 
   for (int i=0; i<PageSize()/2; i++) {
     AddBytes(&q, ByteArrayLiteral(
-      0xD0, 0x1F, 0x00,                       // Set PC to bootsection for spm to work
+      0xD0, hi(bls()), lo(bls()),             // Set PC inside the boot section to enable spm
       0xD2, hi(inr0), lo(inr0), 0x23, *(p++), // in r0,DWDR (low byte)
       0xD2, hi(inr1), lo(inr1), 0x23, *(p++), // in r1,DWDR (high byte)
       0xD2, 0xBF, 0xD7, 0x23,                 // out SPMCSR,r29 (write next page buffer word)
@@ -51,7 +51,7 @@ void ProgramFlashPage(u16 a, const u8 *b
   }
 
   AddBytes(&q, ByteArrayLiteral(
-    0x66, 0xD0, 0x1F, 0x00,              // Set PC to bootsection for spm to work
+    0x66, 0xD0, hi(bls()), lo(bls()),    // Set PC inside the boot section to enable spm
     0xD0, 0, 29, 0xD1, 0, 32,            // Set PC=29, BP=32 - address registers r29 through r31
     0xC2, 5, 0x20, PGWRT, lo(a), hi(a),  // r29 = op (page write), Z = first byte address of page
     0x64, 0xD2, 0xBF, 0xD7, 0x23,        // out SPMCSR,r29 (3=PGERS, 5=PGWRT)
diff -rupN dwire-debug-master/src/dwire/DwPort.c dwire-debug-master.patched/src/dwire/DwPort.c
--- dwire-debug-master/src/dwire/DwPort.c	2017-09-27 19:01:57.596387920 -0400
+++ dwire-debug-master.patched/src/dwire/DwPort.c	2017-10-03 20:38:00.558051921 -0400
@@ -71,6 +71,7 @@ int  SramSize()    {CheckDevice(); retur
 int  EepromSize()  {CheckDevice(); return Characteristics[DeviceType].eepromSize;}
 int  FlashSize()   {CheckDevice(); return Characteristics[DeviceType].flashSize;}   // In bytes
 int  PageSize()    {CheckDevice(); return Characteristics[DeviceType].pageSize;}    // In bytes
+int  bls()         {CheckDevice(); return Characteristics[DeviceType].flashSize - Characteristics[DeviceType].pageSize;}   // In bytes
 int  DWDRreg()     {CheckDevice(); return Characteristics[DeviceType].DWDR;}
 int  DWDRaddr()    {CheckDevice(); return Characteristics[DeviceType].DWDR + 0x20;} // IO regs come after the 32 regs r0-r31
 int  DataLimit()   {CheckDevice(); return 32 + IoregSize() + SramSize();}

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

canbeany1 wrote:

Well, I have my first problem. It hits a breakpoint every time after finishing main, even though there isn't one there.

Unconnected.                            > l /home/a/base/blink/Debug/blink.elf
ttyUSB1 .........
Connected to DebugWIRE device on USB serial port ttyUSB1 at baud rate 123825
Device recognised as ATmega328P
Loading 1038 flash bytes from ELF text segment 0 to addresses $0 through $40d.
                    0000: 940c  jmp   $00$0034              > g
Device reached breakpoint.                                        
main.c[27]          0110: 9598  break                       > 

That's a software breakpoint, isn't it?

 

Devices with dW have only one HW BP register.  Additional breakpoints are handled (by the debugger) by reflashing the page containing the instruction on which you wish to break, and replacing it with the BREAK machine instruction.  When the AVR reaches and executes that instruction while in dW mode, it stops execution, issues a break/sync just as if a HW breakpoint were reached.  Continuing or single-stepping through the breakpoint is accomplished (again, by the debugger) by executing that single instruction via the debug interface (0xD2 hh ll 0x23 command) if it was a single-word instruction, or again reflashing the appropriate page with the original instruction if it was longer.

 

When the breakpoint is finally removed, the flash page is restored to normal with the original instruction where it belongs.

 

If that process were interrupted, then the break instruction will remain in flash, which is why you see it highlighted above instead of the original rjmp instruction.

 

I assume you were using AS to debug that target right before you switched to the dwdebug which showed this strange behaviour?  I'd have to guess that you didn't correctly exit the debug session in AS, and it did not clean up after itself, including and specifically, unravelling software breakpoints.  I assume it was AS, because AFAICT dwdebug lacks the ability to handle software breakpoints in this manner, and I don't think GDB can handle it natively, either.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Curiously, my patch in #34 above doesn't seem to always work.  I'm satisfied that the changes are required, as I was not ever able to program flash without them.  However, even with the changes, sometimes a flash programming operation fails to modify flash.  It appears to be random.  Programming succeeds more than half of the time, but perhaps less than 75% of the time.

 

Possible causes I can think of:

  • Data corruption on the dW line.  I'm running at 63000 baud since the 328P is running at 8 MHz, wherease the t85 is running at 1 MHz with ~7800 baud.
  • I'm not using a proper bypass cap (bad Joey), I only have a 100 uF here at home (surely inadequate).  Mind you, the t85 has no bypass either, but I've had no trouble with it at all.
  • Another flaw in dwdebug I haven't located.
  • Incomplete reverse engineering work for the dW protocol.

 

If anyone can test my patch and report their results, I'd appreciate it.  I'll try the 328P at 1 MHz and see if that makes a difference.

 

EDIT:  1 MHz makes no difference, except that now I can't program flash anymore.  Dunno why.  Returning to 8 MHz doesn't fix the problem.  I'll try bypass caps when I've got some handy.

EDIT2:  It is flashing intermittently.  Not clear what makes it work/fail.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Oct 4, 2017 - 08:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

May I create a GitHub issue from #33?

Or, do you?

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Possible causes I can think of:
Incorrect logic levels

dwire-debug README states 'diode' but not what kind of diode; Schottky diode would increase the voltage margin (reduced forward voltage)

A 5V mega328P and a 3V USB UART would cause current to flow into the UART until the mega328P's debugWIRE goes hi-Z; to correct (in-lieu of a diode), a pass FET with pull-ups.

(am evaluating Exar USB UART)

 


Figure 4. Final interface solutions using a Schottky diode and an external or internal pull-up resistor.

from

Planet Analog

Planet Analog

SIGNAL CHAIN BASICS #66: How to interface a 5V transceiver to a 3V controller

Planet Analog, , 6/25/2012

https://www.planetanalog.com/document.asp?doc_id=528335

from

http://e2e.ti.com/cfs-file/__key/telligent-evolution-components-attachments/00-142-01-00-00-69-72-13/3V-MCU-to-5V-XCVR-Interface.pdf

 

http://www.mouser.com/search/ProductDetail.aspx?R=0virtualkey0virtualkeyBAS70SL

https://www.exar.com/products/interface/uarts/usb-uarts

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is dW electrically very different to uPDI?

'This forum helps those who help themselves.'

 

pragmatic  adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

May I create a GitHub issue from #33?

By all means.  Feel free to propose the patch in #34.

 

Equally troubling is the issue identified in #23/27.  Imagine how frustrating it would be to see r29, r30, and r31 change on their own while debugging.  How long would it take to conclude that the tool was the problem and not one's code? ;-)

 

Incorrect logic levels

True.  That would manifest the same as too high a baud rate.  The curious thing is that none of the other commands seem to behave intermittently.  Only the 'l' command to load flash.  Displaying flash, registers, sram all work fine, writing registers too.

 

I'm running 5V all round.  I've tried at 3.3V and there appears to be no difference.

 

Interestingly, the behaviour is greatly reduced this morning for some unknown reason.  Not eliminated, but nearly.  Frustrating that I cannot correlate it with... anything.

 

Is dW electrically very different to uPDI?

The would both seem to be open-drain wire-and buses.  How they may differ is known to Atmel, but not public.

 

Your thread:

http://www.avrfreaks.net/forum/updi-confusion

... suggests a connection.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mega328P flash write is not performed #27

https://github.com/dcwbrown/dwire-debug/issues/27

joeymorin wrote:
Equally troubling is the issue identified in #23/27.  Imagine how frustrating it would be to see r29, r30, and r31 change on their own while debugging.
May you attach an strace file of that problem?

If so then I'll create the r29 and Z issue.

(see next post)

joeymorin wrote:
The curious thing is that none of the other commands seem to behave intermittently.  Only the 'l' command to load flash.  Displaying flash, registers, sram all work fine, writing registers too.
Insufficient bulk capacitance?

flash writes consume 8mA DC typ approx for the duration of the write with an impulse component due to the boost converter that powers NVM writes.

Could be a voltage regulator instability or a flaky wall wart (unstable or noisy)

4 charged series NiMH cells will power a mega328P; if the AVR is functional on a battery then fails on an LDO or SMPS then that power supply is defective.

The AVR EMC app note states, IIRC, a ferrite bead between the AVR and the voltage regulator; most regulators are conditionally stable.

 

http://ww1.microchip.com/downloads/en/AppNotes/Atmel-1619-EMC-Design-Considerations_ApplicationNote_AVR040.pdf (page 13)

http://www.atmel.com/Images/Atmel-2521-AVR-Hardware-Design-Considerations_ApplicationNote_AVR042.pdf

 


A new arrival at Mouser last week (3S-AAA or 4S-AAA) :

Mouser Electronics

Twin Industries Battery Holders with Machine Pin Jumper Wires

http://www.mouser.com/search/refine.aspx?Ntk=P_MarCom&Ntt=129143400

Twin Industries Battery Holders with male or female machine pin jumper wires support AAA batteries and feature an On/Off switch. The battery holders are designed for easy insertion and extraction in solderless breadboards and other development boards. The robust design supports repeat usage and quick design changes.

The following 2S-AAA with switch would supply an XMEGA or reduced voltage for any AVR :

Microchip Technology Inc

Microchip

Atmel Battery Case 2xAAA

http://www.microchip.com/Developmenttools/ProductDetails.aspx?PartNO=ATBATTERY-CASE-2AAA

AAA cells are a match for most AVR and PIC and for some RF transceivers like LoRa.

LTE transceivers need AA cells (at least)

 

Edit : strikethrus, impulse

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Thu. Oct 5, 2017 - 07:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Author here. Thanks to gchapman for creating the issue on github. Sorry I didn't see this sooner. I hope I can help a bit.

 

Could I ask all of you to build from the littlewire branch? Despite its name you don't need a littlewire - it still supports FT232 and CH430.

 

The littlewire branch includes a lot of changes including I think fixes for all the issues above, in particular:

 

  . support for larger chips with bootloader sections

  . fixes to register 28/29/30/31 handling (sorry about that joeymorin)

  . addition of commands to read/write eeprom

 

Re fuses - sorry, there is just no way to change the fuses from debugWIRE.

 

Re symbols - if you give the load command a .elf file it will load the symbols and use them as follows:

 

 - each line of disassembly is preceded by the source file and line number that generated it

 - labels are inserted into the disassembly

 - constant vales in instruction arguments are annotated with matching symbols

 

History

 

I developed the master branch while tinkering with a t85 in a project for a doorbell that I never finished.

 

Some months later, encouraged by plasticassius, I developed support for littlewire, which has a couple of advantages:

 

 - Speed detection is almost instantaneous

 - the littlewire/digispark also works with avrdude for fuse programming

 

Since then I've been building a remote controlled led strip setup with an atmega328, nRF24L01+ and LCD in the controller, so I hit issues like programming chips with bootloaders and fixed them in the littlewire branch.

 

I've been using it in earnest, so this time round it's been much more fully tested. All recent additions have gone into the littlewire branch.

 

Since the littlewire support caused some quite large reorganisations, I never got around to backporting changes to master. Indeed, my goal is to replace the master branch with the littlewire.

 

So it would be great to get confidence that the littlewire brnach is working for a number of people before I replace the master branch.

 

(I'll also need to write more documentation.)

 

Cheers -- Dave.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dcwbrown wrote:
Author here.

A warm welcome to AVRfreaks then, Dave! I see you've been lurking for a long time.. :-)

 

 

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Johan. FYI re your DWEN fuse postings, dwdebug has a 'qi' - quit to ISP command that quits after temporarily disabling debugWIRE so that the chip is ready for ISP programming eg with avrdude. This doesn't change the dwbugWIRE enable fuse - it's a temporary mode built into all the debugWIRE chips. To get back to debugWIRE mode (assuming you haven't disabled the debugwire flag while in ISP mode) you just cycle the power.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dcwbrown wrote:
FYI re your DWEN fuse postings [...]

Ahhh.. You've seen those - and the lengthy "again..." thread then. (Should I blush now?)  Those are on hold for now, but will be on the top of the stack eventually unless work (as in "the real $ work") block the whole stack.

 

I've been silently monitoring this thread since it started as it may have tips, tricks or alternatives re my dabbling.

 

The "qi" scheme you're describing seems to be similar to what Studio claims to do when one is exiting a debug session, as I understand it.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could I ask all of you to build from the littlewire branch? Despite its name you don't need a littlewire - it still supports FT232 and CH430.

Had I only gone up a level on GitHub... :)

 

I'll check it out, but likely not until next week.

 

Many thanks.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just for giggles before I have to turn my attention elsewhere, I though I'd try to build it:

$ cd ./software/
$ make
Building library: littleWire...
gcc `libusb-config --cflags` `libusb-config --libs` -Ilibrary -O -g -D LINUX -c library/littleWire.c
Building library: littleWire_util...
gcc `libusb-config --cflags` `libusb-config --libs` -Ilibrary -O -g -D LINUX -c library/littleWire_util.c
Building library: littleWire_servo...
gcc `libusb-config --cflags` `libusb-config --libs` -Ilibrary -O -g -D LINUX -c library/littleWire_servo.c
Building library: opendevice...
gcc `libusb-config --cflags` `libusb-config --libs` -Ilibrary -O -g -D LINUX -c library/opendevice.c
Building example: debugWIRE...
gcc `libusb-config --cflags` `libusb-config --libs` -Ilibrary -O -g -D LINUX -o debugWIRE examples/debugWIRE.c littleWire.o littleWire_util.o littleWire_servo.o opendevice.o `libusb-config --libs`
gcc: error: examples/debugWIRE.c: No such file or directory
Makefile:44: recipe for target 'debugWIRE' failed
make: *** [debugWIRE] Error 1

Via makefile:

#EXAMPLES  = adc blink blink_ws2812 rgb_cycle_ws2812 fade_ws2812 button servo i2c_blinkM
#EXAMPLES += spi_LTC1448 onewire softPWM hardwarePWM debugConsole lwbuttond i2c_nunchuck
EXAMPLES += debugWIRE

No such file as debugWIRE.c anywhere in the .zip.

I spent a few minutes looking for an obvious problem and solution, none jumped out.

 

Similarly, trying to build from within the example:

$ cd ./examples/debugWIRE
$ make
gcc -std=gnu99 -g -fno-pie -rdynamic -fPIC -Wall -o dwdebug src/dwdebug.c `libusb-config --cflags` `libusb-config --libs` -I ../../library -DNOFILEDIALOG
In file included from src/../../../library/opendevice.c:18:0,
                 from src/dwdebug.c:4:
src/../../../library/opendevice.h:29:82: fatal error: lusb0_usb.h: No such file or directory
compilation terminated.
Makefile:77: recipe for target 'dwdebug' failed
make: *** [dwdebug] Error 1

Again, no lusb0_usb.h file to be found anywhere.

 

Files containing references to lusb0_usb.h:

$ grep -lr lusb0_usb[.]h .
./software/examples/debugWIRE/src/system/SystemServices.c
./software/library/littleWire.h
./software/library/opendevice.h

 

./software/examples/debugWIRE/src/system/SystemServices.c:

#ifdef windows
  #include <winsock2.h>
  #include <windows.h>
  #include <time.h>
  #include <stdint.h>
  #include <stdio.h>
  #include <setjmp.h>
  #include <lusb0_usb.h>
  #undef min
  #undef max
  void delay(unsigned int ms) {Sleep(ms);}
#else

 

./software/library/littleWire.h:

#if defined(LINUX)
   #include <usb.h>				// this is libusb, see http://libusb.sourceforge.net/
#else
   #include <lusb0_usb.h>		// this is libusb, see http://libusb.sourceforge.net/
#endif

 

(The offending) ./software/library/opendevice.h:

#if defined(LINUX)
   #include <usb.h>			// this is libusb, see http://libusb.sourceforge.net/ 
#else
   #include <lusb0_usb.h>		// this is libusb, see http://libusb.sourceforge.net/ 
#endif

 

So, seems LINUX isn't defined, despite:

./software/examples/debugWIRE/Makefile:

ifeq ($(shell uname), Linux)
	USBFLAGS = `libusb-config --cflags`
	USBLIBS = `libusb-config --libs`
	EXE_SUFFIX =
	OSFLAG = -D LINUX
else ifeq ($(shell uname), Darwin)
	USBFLAGS = `libusb-config --cflags`
	USBLIBS = `libusb-config --libs`
	EXE_SUFFIX =
	OSFLAG = -D LINUX
else
	USBFLAGS = -I D:\projects\gcc\libusb-win32-bin-1.2.6.0\include
	USBLIBS = -L D:\projects\gcc\libusb-win32-bin-1.2.6.0\lib\gcc -lusb
	EXE_SUFFIX = .exe
	OSFLAG = -D WIN
endif

 

This is because, in the same file, OSFLAG isn't part of any recipe.  In ./software/Makefile, it's added into CFLAGS:

ifeq ($(shell uname), Linux)
	USBFLAGS = `libusb-config --cflags`
	USBLIBS = `libusb-config --libs`
	EXE_SUFFIX =
	OSFLAG = -D LINUX
else ifeq ($(shell uname), Darwin)
	USBFLAGS = `libusb-config --cflags`
	USBLIBS = `libusb-config --libs`
	EXE_SUFFIX =
	OSFLAG = -D LINUX
else
	USBFLAGS = -I D:\projects\gcc\libusb-win32-bin-1.2.6.0\include
	USBLIBS = -L D:\projects\gcc\libusb-win32-bin-1.2.6.0\lib\gcc -lusb
	EXE_SUFFIX = .exe
	OSFLAG = -D WIN
endif

LIBS    = $(USBLIBS)
INCLUDE = library
CFLAGS  = $(USBFLAGS) $(LIBS) -I$(INCLUDE) -O -g $(OSFLAG)

... and CFLAGS is explicitly passed in the recipes.

 

In ./software/examples/debugWIRE/Makefile, you use FLAGS instead of CFLAGS, so I added to it:

FLAGS = $(USBFLAGS) $(USBLIBS) -I ../../library $(OSFLAG) -O -g

Note that I also added -O (-O0 is always a bad idea) and -g.

 

Now:

$ make
gcc -std=gnu99 -g -fno-pie -rdynamic -fPIC -Wall -o dwdebug src/dwdebug.c `libusb-config --cflags` `libusb-config --libs` -I ../../library -D LINUX -O -g -DNOFILEDIALOG
In file included from /usr/include/x86_64-linux-gnu/sys/select.h:128:0,
                 from /usr/include/x86_64-linux-gnu/sys/types.h:219,
                 from src/system/SystemServices.c:19,
                 from src/system/system.c:1,
                 from src/dwdebug.c:3:
src/commands/GoCommand.c: In function ‘GoWaitLoop’:
src/commands/GoCommand.c:65:14: error: ‘SerialPort’ undeclared (first use in this function)
       FD_SET(SerialPort, &readfds);
              ^
src/commands/GoCommand.c:65:14: note: each undeclared identifier is reported only once for each function it appears in
Makefile:77: recipe for target 'dwdebug' failed
make: *** [dwdebug] Error 1

And this is where I gave up, because:

Current status

 

Builds firmware and working DigiSpark-only dwdebug for Windows only.

 

Further work now moving to github.com/dcwbrown/dwire-debug branch 'lwire'.

 

So, I can't help you (and you can't help me!) if that is the case.

 

Suggestions?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you!

dcwbrown wrote:
- Speed detection is almost instantaneous
What bounds the speed?  (debugWIRE physical, debugWIRE engine)

Reason : fast USB UART versus enhanced Little Wire

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oops, I was obtuse when I waffled 'the littlewire branch' wasn't I?

 

Yep you've been trying to build an obsolete repository. Sorry about that.

 

What I should have said was, 

  .  stay in the dwire-debug repository

  .  type git checkout lwire to switch to the littlewire branch

  .  run make from the root of the repository

 

Hopefully this will help ...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The speed of detection is (much) slower for the UART than the LittleWire/Digispark because:

 

The UART code works out the speed by repeatedly sending a break initially at a high baud rate and guessing from the mess of bits that the UART decodes how much slower a baud rate to try next. Once it has found a baud rate that works one time, it tries some more speeds just a little faster and just a little slower to get a bracket of working speeds, choosing the middle of that bracket as a reliable speed. By the time it has worked out a reasonably reliable rate it has sent a break around a dozen times, and a break is slow - much longer than a character. 

 

whereas:

 

The littlewire code monitors the debugWIRE line directly in assembly code and times the pulses coming back as a result of just one break.

 

-- Dave.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the information.

The duration of speed detect may not be a concern as that's relatively short compared to the session's duration.

Where speed detect's duration would be a concern is for repeated resets or power cycles (unit testing, integration testing, BIT during PCBA manufacturing)

Wasn't aware of the speed detect advantage of enhanced Little Wire.

Since debugWIRE's bit frequency is adequate or more than adequate then advantage to Little Wire.

Little Wire is also easy to implement due to the ubiquity of tinyAVR 5s.

 

Was inquiring about the max speed of debugWIRE but that's moot because RESET(dW) is "slow" (strong pull-down, weak pull-up of 2K ohms typical at 5V) with an estimated max speed of 200Kbps.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
That would manifest the same as too high a baud rate.

...

Frustrating that I cannot correlate it with... anything.

ambient temperature

Hypothesis:

Switching diode's forward voltage is close to RESET's limit of 0.1 * Vcc (500mV for 5V)

 

Tool:

Heatgun

 

Test:

Heat the diode halfway to boiling.

Is dwire-debug functional?

 

Proposed Solution:

Schottky diode

One of many is BAS70 from http://www.avrfreaks.net/forum/debugwire-usb-uart#comment-2287616 at Cjo of 3pF (or near equivalent)

1N5817 is leaky with a Cjo of 200pF but it'll still work.

SB120 leaks less with a bit less Cjo.

 

Correction:

Needs to be a low Cjo Schottky as a 5V USB UART with a low Vcc AVR will cause RESET(dW) -0.5V limit to be exceeded.

SB120 would be better though the best solution is to patch a low Cjo SMD Schottky.

Maybe one from the RB751 series but its forward voltage may be too large for a low Vcc AVR that's at freezing ambient.

BAT54 is better; SOD123 or SOT23 (single, not the duals), low forward voltage well below freezing, leaky, capacitance of 10pF max is too large for 5V USB UART and 2.5V AVR

BAT54 is from more than several manufacturers; can be patched (1.8mm or 3.3mm pitch) though would be easier on a snippet of protoboard (can add pins and/or sockets to create a dwire-debug adapter)

 

To reduce EOS with a USB UART and AVR (large) voltage mismatch, insert a 499 to 1Kohm resistor between USB UART TXD and BAT54's cathode.

This will be marginal (dW floor, overshoot) with a 2V AVR.

The excessive overshoot is corrected by decreasing TXD's transition speed via inserting a capacitor to ground between an 499 ohm resistor and the Schottky diode's cathode; 1nF for 1N5817, 47pF for BAT54.

 

Note:

RESET(dW) doesn't have an ESD diode to VCC so observe your ESD training.

If concerned, there are low Cjo TVS that will clamp well before RESET's 13V abs max yet not leak too much at 5V operating.

ESD damage initially manifests as leaky transistors unless the ESD/EOS/EFT/lightning has enough energy then the FET's body diode will short or the gate oxide will be punched through.

Some ESD generates enough EMP to destroy electronics across a small room due to induction (wires are an antenna)

Could try a new mega328P if you think the current one's RESET(dW) signal is flaky or the EOS may have damaged the debugWIRE machine.

 


http://www.onsemi.com/PowerSolutions/product.do?id=BAS70SL (SMD)

http://www.onsemi.com/PowerSolutions/product.do?id=1N5817 (thru-hole)

http://www.onsemi.com/PowerSolutions/product.do?id=SB120 (thru-hole)

http://www.onsemi.com/PowerSolutions/product.do?id=RB751S40 (SMD)

http://www.onsemi.com/PowerSolutions/product.do?id=BAT54 (SMD)

 

Edits : correction, RB751, BAT54, resistor, capacitor

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Wed. Oct 11, 2017 - 04:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
Is dW electrically very different to uPDI?
Yes

Like PDI, UPDI is symmetric impedance with tri-state whereas dW is open drain with active and hold pull-ups.

 

Edit : pull-ups

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Tue. Oct 10, 2017 - 06:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The debugWIRE hardware implementation fixes the baud rate at target clock speed/128.

 

So an estimated max speed of 200Kbps would theoretically support targets of up to 128 x 200KHz = 25.6MHz, a little more than the official 20MHz max speed of these AVR devices.

 

It works for me with short separated wires. I would avoid long wires, especially in close proximity as in a multiway flat cable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The work by RikusW suggests baud rates as high as /8 are available, with /128 the default. Have you determined this to be untrue?

I realise that bus characteristics will dictate the maximum attainable speed, but smaller prescalers would permit faster dW comms with lower system clock speeds.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Incorrect logic levels

tiny85

Input Low-voltage, RESET pin

VIL2 < 0.2 * VCC

 

mega328P

VIL2 < 0.1 * VCC

 

Though not as ubiquitous as a Schottky diode, a level converter would be functional for all dW AVR at all Vcc for the full temperature range for any voltage USB UART.

Some of the packages for such are SOIC and SOT23 so would be easy to protoboard.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh yes! I just looked at RikusW's notes again. I'd forgotten all about that so I never got around to trying it.

Mostly the clock/128 speed is fine.

The only time I wouldn't mind a faster connection is when programming a lot of flash, but it's not really been a serious issue.

dwdebug is very careful not to erase or program unnecessarily.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I agree logic levels could be to blame, but we're that the case I would expect all operations to exhibit the same hit/miss ratio.  I also agree that the added load of erase/program operations could tip the scales, but we're that the case I would expect that erase operations would fail in equal measure to write operations.  They do not.  I had been using an all-0xFF binary file to 'erase' the chip during testing.  I don't believe I have seen that fail.  Only write operations with 'non-empty' payloads seem to fail.

I have more testing to do, and I'll implement your suggestions, but it will likely not happen until at least next week, because I am here:

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Filling the barn with hay and/or chopping fire wood I would guess before winter.

Or painting the barn red???

 

Jim

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Actually, just visiting.  Not a working farm any more.

 

But it is far from my workshop ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The only time I wouldn't mind a faster connection is when programming a lot of flash, but it's not really been a serious issue.

dwdebug is very careful not to erase or program unnecessarily.

Single-stepping via GDB/DDD or similar, with data watch windows, can require polling large data blocks and the entire register file.  Would be nice if that could be faster.  I notice a real difference between running a 1 MHz target with a 7.8kbps dW speed v.s. a 16 MHz target with a 125kps dW speed.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Builds firmware and working DigiSpark-only dwdebug for Windows only.

Further work now moving to github.com/dcwbrown/dwire-debug branch 'lwire'.

joeymorin wrote:
So, I can't help you (and you can't help me!) if that is the case.

 

Suggestions?

fyi, the following issue closed today.

GitHub

/dwire-debug

build errors in linux version #23

https://github.com/dcwbrown/dwire-debug/issues/23

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sweet!  Don't know when I'll have time to give this attention, but it is high on my list.  Thanks for the update!

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

OK, I couldn't wait.  A quick build and test with a 328P suggests the problems I had earlier with intermittent success at programming the328P have disappeared.  A quick return to the old build shows those problems remain intermittent, so whatever it was appears to have been resolved with the latest repo.

 

r29 issue appears to have been remedied as claimed.  Other testing will have to wait.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just to be clear, I built from the lwire repo as suggested by the author in #49:

Oops, I was obtuse when I waffled 'the littlewire branch' wasn't I?

 

Yep you've been trying to build an obsolete repository. Sorry about that.

 

What I should have said was, 

  .  stay in the dwire-debug repository

  .  type git checkout lwire to switch to the littlewire branch

  .  run make from the root of the repository

 

Hopefully this will help ...

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
Flash is not written under an ATmega328P.  The load operation proceeds without errors, but flash is not modified.
Fixed by merging the Little Wire branch into the master branch via an issue that was closed today.

Programming does not work #29

https://github.com/dcwbrown/dwire-debug/issues/29

...

a-v-s commented a day ago

I am using a HL-340 USB-TTL adaptor.
I can connect to a ATMEGA328P through dwdebug and debug it. However, ...

...

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, that was short-lived.

 

The latest version barfs with this shortly after ddd connects (via avr-gdb) with 'target remote':

Attempt to read beyond end of flash.

... while ddd reports:

Remote connection closed

 

Seems ddd tries to fetch machine code past the end of flash, and dwdebug terminates.  While ddd probably shouldn't do that, I didn't have that problem with the older version of dwdebug.

 

One step forward, two steps back :(

 

Anyone know how to tell ddd how big flash is, and/or how not to read past the end?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Scratch that.  The other version did that as well.  I'll have to do more testing to figure out what's stopping me from making headway with the new version.

 

Still interested in getting ddd to play nice with dwdebug.

 

Any other gdb front ends apart from ddd which someone can recommend?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sat. Oct 21, 2017 - 06:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gdbgui?

(haven't tried it)

 

GDB Wiki

GDB Front Ends

https://sourceware.org/gdb/wiki/GDB%20Front%20Ends

...

1.1. Using modern GDB/MI

GDB/MI is a line based machine oriented text interface to GDB. It is specifically intended to support the development of systems which use the debugger as component of a larger system. See The GDB/MI Interface in the GDB manual.

gdbgui - Feature rich browser-based frontend with data structure visualizations (like DDD), and gdb terminal access. Compatible with C, C++, golang, Rust, fortran. Written in Python and JavaScript. pip install gdbgui.

...

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I figured out what I was doing wrong with ddd and reading beyond the end of flash.  It had to do with the order in which I issued commands to ddd.

 

Now, of course, there are other issues.

 

The machine code doesn't show flash contents, but SRAM:

Dump of assembler code from 0x80001e to 0x80011e:
   0x0080001e:  std     Y+50, r10       ; 0x32
   0x00800020:  nop
   0x00800022:  nop
   0x00800024:  nop
   0x00800026:  nop
   0x00800028:  nop
   0x0080002a:  nop
   0x0080002c:  nop
   0x0080002e:  nop
   0x00800030:  nop
   0x00800032:  nop
   0x00800034:  nop
   0x00800036:  .word   0x0004  ; ????
   0x00800038:  nop
   0x0080003a:  nop
   0x0080003c:  nop
   0x0080003e:  movw    r30, r8
   0x00800040:  nop

Note the addresses which start at 0x800000.

 

Compare that to a data dump from the dwdebug command line:

> d0 50
0000:   ff 00 ff 60  04 01 10 80   12 19 0a 11  00 21 25 06   ...`.........!%.
0010:   81 01 00 00  20 f2 06 6c   3f 00 06 b0  5f 00 2f 00   .... ..l?..._./.
0020:   00 00 00 00  00 00 00 00   00 00 00 00  00 00 00 00   ................
0030:   00 00 00 00  00 00 04 00   00 00 00 00  00 00 54 01   ..............T.
0040:   00 00 00 00  00 00 00 03   00 00 00 00  00 ff 00 00   ................

Note how the content of address 0x1e through 0x40 match that of the machine code view from ddd, confirming that it is pulling from SRAM and not flash.  Except for the word at 0x001E (which is EEARH:L), and at 0x003E (which is SPH and SREG), the remaining words match, so it would seem that flash addresses are getting converted to SRAM addresses before issuing the commands to the avr-gdb backend.

 

In a similar vein, attempts to display data memory fail with addresses associated with SRAM i.e. offset by 0x800000.

 

I'm afraid I have no idea how to drive this thing, and debugging directly at the dwdebug command line seems onerous.  I'll likely live without debugging for a while yet ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]