I finally got over my problems getting the micro up and running, so I should able able to get a really good test of the PWM DAC working today.
It am using a atmega328 running at 16MHz. Since I do not have the constraints George had, I am able to write the interrupt in C. I can easily fit the interrupt code for managing two timers inside the 16uS PWM period. It will probably end up using something like 8uS, so that is all I need for a good test.
This code does not use any dedicated registers - just standard RAM memory - so it is not nearly as efficient as George's code. There is a good chance I will end up using George's code in a final version, except if I use a micro that does not have a built-in clock multiplier for the PWM clock, then I will not use dedicated registers.
Here is the C code with the assembler the compiler generated:
ISR(TIMER2_OVF_vect) {
b2a: 1f 92 push r1
b2c: 0f 92 push r0
b2e: 0f b6 in r0, 0x3f ; 63
b30: 0f 92 push r0
b32: 11 24 eor r1, r1
b34: 2f 93 push r18
b36: 3f 93 push r19
b38: 4f 93 push r20
b3a: 5f 93 push r21
b3c: 8f 93 push r24
b3e: 9f 93 push r25
b40: af 93 push r26
b42: bf 93 push r27
OCR2A = (byte) (pwm_accum / 0x01000000L ) ; // 16 cycles
b46: 80 91 80 01 lds r24, 0x0180
b4a: 90 91 81 01 lds r25, 0x0181
b4e: a0 91 82 01 lds r26, 0x0182
b52: b0 91 83 01 lds r27, 0x0183
b56: 2b 2f mov r18, r27
b58: 33 27 eor r19, r19
b5a: 44 27 eor r20, r20
b5c: 55 27 eor r21, r21
b5e: 20 93 b3 00 sts 0x00B3, r18
pwm_accum &= 0x00FFFFFFL ; // 7 cycles
b62: b0 70 andi r27, 0x00 ; 0
b64: 20 91 7c 01 lds r18, 0x017C
b68: 30 91 7d 01 lds r19, 0x017D
b6c: 40 91 7e 01 lds r20, 0x017E
b70: 50 91 7f 01 lds r21, 0x017F
pwm_accum += value ; // 11 cycles
b74: 82 0f add r24, r18
b76: 93 1f adc r25, r19
b78: a4 1f adc r26, r20
b7a: b5 1f adc r27, r21
b7c: 80 93 80 01 sts 0x0180, r24
b80: 90 93 81 01 sts 0x0181, r25
b84: a0 93 82 01 sts 0x0182, r26
b88: b0 93 83 01 sts 0x0183, r27
}
b8e: bf 91 pop r27
b90: af 91 pop r26
b92: 9f 91 pop r25
b94: 8f 91 pop r24
b96: 5f 91 pop r21
b98: 4f 91 pop r20
b9a: 3f 91 pop r19
b9c: 2f 91 pop r18
b9e: 0f 90 pop r0
ba0: 0f be out 0x3f, r0 ; 63
ba2: 0f 90 pop r0
ba4: 1f 90 pop r1
ba6: 18 95 reti
I am really impressed that the code optimizer translated
OCR2A = (byte) (pwm_accum / 0x01000000L )
into a move, and three exclusive ORs and a sts command. It didn't try to divide at all. It could have left out the eor commands, but that is just 3 cycles.
Richard.