Go Down

Topic: QUUBmon - yet another monitor program (Read 13658 times) previous topic - next topic


I am not using the ICSP header, I guess that is the problem.

I initially used the ICSP header but found I couldn't upload sketches while it was connected (something to do with the reset line I think).

Also, the ICSP header does not bring out SS.

My testing used just connecting the 4 pins (MISO, MOSI, SCK, SS)  plus 5V and Gnd.

If you are outputting debugging make sure you capture to a buffer first. Serial comms is much slower than SPI.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics


Sep 04, 2011, 12:38 am Last Edit: Sep 04, 2011, 12:54 am by caroper Reason: 1
You are an early riser Nick:)

I have been having some thoughts on the Debug Monitor, i particular having the DUT as master and Monitor as slave.
Logically I would put it the other way round, so that the the monitor can interrupt the DUT at any time to request info, and the DUT could use a BREAKPOINT macro to interrupt the Monitor at points determined by the programmer.

I know that nether of you include breakpoints but it would be a logical extension.


the macro would be something like this:
#define BreakPoint if(debug)digitalWrite(BPReq, 0)
that way by turning off debug via the monitor the code would run at almost full speed until the Monitor interrupts and turns debugging back on.
DebugPrint could work by writing to an output buffer and then flagging the IRQ without doing the Debug Test.


It's almost 9 am!

Yes, I didn't go as far as Rob with breakpoints and stuff. I was more thinking along the lines of tapping into existing SPI messages. For advanced debugging there is stuff like the Dragon board and I believe you can do hardware debugging through the reset pin, but I haven't attempted anything like that.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics


I was busy editing the post above and didn't notice your reply Nick.

I have been programming a spare Mega as a breadboard tool that would provide services to any circuit I am testing.
Currently it can generate a clock Signal up to 8MHz
Has a Frequency Counter
Period / Duty Cycle Timer for testing PWM
Digital Stopwatch / Pulse Timer for testing low frequency events such as RPM etc.
acts as a USB to Serial pass through
Powers the DUT
and having found your thread and this one I decided to see if I could add a basic debugging tool as AVR, PIC and freesecale all support SPI.
It is mostly for fun whilst I wait for a prototype PIC32 board to arrive, but it has proven useful in breadboarding the PIC32 application up to this point.


What you are seeing is correct behavior. The server is expecting 5 bytes from the client


it then sends two bytes back


In your case CMD is 0x00 which is not a valid command so RESP1 is a NAK.

This will occur every 16mS or so.

Logic analyzer does not decode SPI bytes if SS is not low

That also caught me for a while (I was having a bad day) but then I found that you can set "Enable" to "None" and it will ignore the SS line. This is with version 1.1.11 of the software.

Rob Gray aka the GRAYnomad www.robgray.com


Sep 04, 2011, 08:58 am Last Edit: Sep 04, 2011, 09:28 am by Graynomad Reason: 1
Yay it's working.

I have the client working on a 2560 and server on a 328. What a bloody drama and to be honest i still don't exactly know what the trouble was. I just rewrote half the code :)

Latest code


Chris, if you could give it a try that would be good.

As for break points, that will be difficult because you have to write into flash. Doable I guess but not easy.

Here's a list of commands
RD - Read a single byte from the target RAM.
WR - Write a byte to target RAM.
L - Do a HEX dump of 16 bytes (a “line”) from the target RAM.
P - Do a HEX dump of 128 bytes (a “page”) from the target RAM.
REGS - Display the target processors registers (only with an assembly language server)
IO - Display the target processor’s IO registers.
F - Fill target RAM with a value.
SP - Display the target processors stack pointer and the values on the stack.
PER - Display detail about the target processor’s “peripherals”.
WATCH - Periodically sample a memory or IO location on the target processor.
RST - Reset the target processor.
IPC ? - Find the IPC (Inter Processor Comms) area of RAM on the target system.
IPC - Dump the IPC (Inter Processor Comms) area of RAM on the target system.
SET - Set a variable in the IPC.
DIG - Display all Arduino digital pin values on the target system.
AN - Display all Arduino analogue pin values on the target system.
PIN - Display and control Arduino digital pins.
PC - Display the target processor’s program counter.
INFO - Get information about the target system.

Note that a lot of them are disabled and there's still plenty of debug code hanging around.

Rob Gray aka the GRAYnomad www.robgray.com


The reason I have the master/slave relationship with the DUT as master is to allow the monitor to be as less intrusive as possible. Granted there is an interrupt every 16mS (maybe an on/off facility would be good) but this is only ~5% of the CPU time (my original assembler version was better) and with bit banging any pins can be used. You can't debug an SPI port if you are using it for debugging as well.

I currently use the SPI pins but that's just for convenience with the cable between ISP headers. Any other pins can be used.

Anyway that's the general idea.

Also I just read you breakpoint idea, I was thinking of proper software breakpoints that need flash to be written, but yes you could toggle a pin to cause an interrupt which in turn could say enable the monitor. The monitor could also run with full control or in the background as it does now. I think having both is good because a lot of programs will break if you stop in a monitor. 

Any thoughts are welcome.

Rob Gray aka the GRAYnomad www.robgray.com


Thanks Rob,

Success :)
Code: [Select]

AVRmon v1.0Compiled for  Server: ATmega2560  Client: ATmega2560on Sep  4 2011

Server offline.AVR> bad frame
Server online.AVR> tmr0
GTCCR--->043-->00 0-----00 0:tsm                                                       6:psrasy  7:psrsync
TCCR0A-->044-->03 0000--11 0:com0a1  1:com0a0  2:com0b1  3:com0b0                      6:WGM01   7:WGM00   
TCCR0B-->045-->03 00--0011 0:foc0a   1:foc0b                       4:wgm02   5:cs02    6:CS01    7:CS00   
TCNT0--->046-->AD 10101101 0:HI      1:lo      2:HI      3:lo      4:HI      5:HI      6:lo      7:HI     
OCR0A--->047-->00 00000000 0:lo      1:lo      2:lo      3:lo      4:lo      5:lo      6:lo      7:lo     
OCR0B--->048-->00 00000000 0:lo      1:lo      2:lo      3:lo      4:lo      5:lo      6:lo      7:lo     
TIMSK0-->06E-->01 -----001                                                   5:ocie0b  6:ocie0a  7:TOIE0   
TIFR0--->035-->06 -----110                                                   5:OCF0B   6:OCF0A   7:tov0   

I look forward to playing with this tool, just that one command alone can potentially save me hours of frustration, as I am building a app that uses any or all of the 5 timers, just being sure that the correct timer was configured is worth its weight in gold.



Awesome project Rob.

The typedef you have for your struct is missing the name of the typedef.  It should be something like this:

Code: [Select]
typedef struct s_reg {
unsigned int address;
char name[8];
char bits[8][9];
} reg;

The s_reg is name of the struct rather than the typedef, handy if you want to reference the struct inside the struct.


Sep 04, 2011, 11:06 am Last Edit: Sep 04, 2011, 11:11 am by Graynomad Reason: 1

Thank goodness. I'll spend some time tidying things up and maybe reinstating some of the commands.

I know 99% of people don't need such a tool but just to have a second opinion on the values in - for example - the timer regs is valuable I think. It's one thing to "know" you wrote 55 into a reg, quite another to have that verified by an independent tool and maybe see the value 37 and realize that you should have typed 0x55.

As you may have seen the "peripherals" are just lists of data structures and addresses and as such they are arbitrary and configurable. For example all the timers have their own regs but also share the GTCCR reg. So all the tmr0/1/2/3 etc commands show the GTCCR reg as well as those regs unique to the separate timers.

Thus "peripherals" are logical, not literal. Another example of a logical peripheral is the "mcu" peripheral, this shows all sorts of regs like the status reg, stack pointers, OSCALL etc.

In the above screen dump by Chris, UPPERCASE bit names is a set bit, lowercase is a cleared bit.

As all this was hand entered there are bound to be some mistakes, hopefully they will get sorted over time.

Some other points re the UI.

TAB - repeat the last command
UP ARROW - recall the last command to the screen

The address used by a command is remembered, so if you do "P 100" to dump the page at address 100 you can follow that with just "P" (or "L" for that matter) and get a dump from the same location.

handy if you want to reference the struct inside the struct.

Like with a linked list.

Thanks s_reg, I'l mod the code.
Rob Gray aka the GRAYnomad www.robgray.com


Hi Rob,

I have run through the command set and all appears 2 work apart from AN which returns from 1 to 5 values before the client hangs.
I also couldn't work out how to use the SET command and INFO seams to return the same result as IPC, is that by design?

This is a great tool, having tested its command set it has even more potential than I first envisaged.
Thanks a ton for sharing it Rob, and the effort you put in, well above the call of duty, to get it working on my bench.



Sep 04, 2011, 11:47 am Last Edit: Sep 04, 2011, 11:52 am by Graynomad Reason: 1
the SET command

I guess the documentation is not up to scratch yet :)

SET will write a value into the IPC, so backing up, what's the IPC?

The IPC (Inter Processor Communications) area is a few bytes in the target (server/DUT) RAM that both server and client know about. Therefore the client (monitor) can write into this memory and the server application can take action based on that data.

There is a simple example in the server code

Code: [Select]
  // use "SET 3 0" to start the LED flashing
  // use "SET 4 n" to set the flash rate
  if (QM_ipc_scratch[3] == 0) {
    digitalWrite(13, HIGH);   // set the LED on
    digitalWrite(13, LOW);    // set the LED off

Entering "SET 3 0" (write 0 into offset 3) into the monitor should cause the server to start flashing the LED while "SET 4 n" will change the flash rate. Silly example but this should be usable - for example - to play with values for an algorithm without having to recompile.

Conversely if you mirror a server variable into the IPC (or just use the area directly) you can read it from the monitor.

Obviously you can read RAM anywhere but in the absence of symbolic information (a good project BTW, to read the MAP/ELF/whatever file and use symbols) this is a reasonable alternative.

As I didn't know how to force the address of the IPC (another thing to look into) there's the "IPC ?" command to find it.

INFO seams to return the same result as IPC

They both dump the IPC memory but INFO first writes some DUT info into the memory. Here's one after the other

Code: [Select]
AVR> ipc
0131:  49 50 43 20 73 63 72 61 74 63 68 20 52 41 4D 00    IPC scratch RAM.
AVR> info
0131:  42 03 04 05 0C 0B 0D 61 03 28 01 01 52 41 4D 00    B......a.(..RAM.
AVR> ipc
0131:  42 03 04 05 0C 0B 0D 61 03 28 01 01 52 41 4D 00    B......a.(..RAM.

Note that the first IPC shows the default data in the RAM, the string "IPC scratch RAM". INFO shows the same RAM but the string has been overwritten. And the next IPC shows the same as the INFO for that reason.

It's a bit cryptic but

42 "B", the port used by the server for bit banged SPI
03 IO port MOSI pin
04 IO port MISO pin
05 IO port SCK pin
0C Arduino D pin # for MISO
0B Arduino D pin # for MOSI
0D Arduino D pin # for SCK
61 not used
03 server processor hi byte
28 server processor lo byte   (0328 = mega328, you should see 2560 I think)
01 server code version hi byte
01 server code version lo byte (server code version 01.01)

Of course you probably know most of the above or you wouldn't be seeing the data in the first place, so I don't know how useful it is. Seemed like a good idea at the time :)

AN works for me but my server is a 328 that only has 6 analogue ports anyway, maybe the structure is not properly defined for a 2560.

Thanks a ton for sharing it Rob,

No problems, good to see it being used. There wasn't much interest at the time and I had no immediate use for it myself as I was designing hardware (still am), so I didn't clean it up and add stuff I would have liked to.

Rob Gray aka the GRAYnomad www.robgray.com

Go Up