.:madworm:.'s photos with the keyword: logic analyzer
Cured subject
08 Jul 2011 |
|
No more hick-ups to be found. The solution is 'dirty', but works in this case. As the soft-uart only deals with 9600bps, which is rather slow, I made the pin-change interrupt that samples the byte interruptible. The delays introduced by all the other ISRs are minuscule and don't matter ;-)
The other way around would be lethal.
What happened:
The ISR that deals with the LEDs runs in CTC mode, that is the timer value is reset to zero, once a compare match has occurred. Now if other interrupts delay the invocation of said ISR, the timer will have advanced beyond the usual compare match value and will have to wrap around completely. A 16bit timer will need quite a while in this case (2s). In practice the LEDs will shut off for that period. Ouch.
Mental illness in microcontrollers
08 Jul 2011 |
|
The top signal shows the premature death of the ATtiny24's TIM1_COMPA_vect. In hindsight the explanation is trivial, but I didn't suspect that cause until very late in the debugging process - as usual.
The patient is well again !
08 Jul 2011 |
|
From top to bottom: a) Interrupt servicing the LED drivers with PWM pulses. It only runs when the edges need to change and takes very little time. But it is crucial that its timing is 100% spot on. b) LED driver enable signal produced by the ISR. c) pin-change interrupt that reads incoming serial data @9600. d) pulses indicate when the bit are sampled, which is tuned by inserting fixed delays. e) incoming serial data. f) status LED showing something I can't remember right now.
Sniffing SPI traffic - RLE enabled
Sniffing SPI traffic - RLE enabled
Sniffing SPI traffic - RLE enabled
Sniffing SPI traffic - RLE enabled
07 Jul 2011 |
|
Drilling down...
BTW, I was just zooming in. All the data comes from the same scan.
BAD BAD 127 / 128 transition
17 Jan 2012 |
|
The moving average spikes... this is visible as a bright flash ;-(
Very bad when fading - and that is the whole purpose of this exercise.
www.picbasic.co.uk/forum/showthread.php?t=7393
www.picbasic.co.uk/forum/showthread.php?t=10564
Debugging avrdude - arduino.c
16 Jul 2011 |
|
I've had issues uploading code with avrdude 5.10 and the new optiboot bootloader.
Starting values - 1st pulse
Starting values - 8th pulse
Starting values - overview
21 Jul 2011 |
|
By accident I had observed that the runtime gets longer and longer. See here as well.
Code excerpt:
if(bit <= 7) { // read data-bits 0...7
if( (PINA & _BV(PA0)) ) {
soft_uart_rx_byte |= _BV(bit);
} else {
soft_uart_rx_byte &= ~_BV(bit);
}
[...]
As shown here , the _BV(bit) part gets turned into a loop. As 'bit' is a variable, it can't be replaced by a number at compile time. And the loop gets longer for higher bits.
1st optimization attempt
21 Jul 2011 |
|
When dealing with this I realized (finally) that I could remove duplicate code and use this as the replacement:
uint8_t bit_value = _BV(bit);
if(bit <= 7) { // read data-bits 0...7
if( (PINA & _BV(PA0)) ) {
soft_uart_rx_byte |= bit_value;
} else {
soft_uart_rx_byte &= ~bit_value;
}
[...]
Now the _BV(bit) expression has to be evaluated just once. But that didn't help at all. It seems the compiler had already optimized the previous code.
1st optimization attempt - 1st pulse
1st optimization attempt - 8th pulse
Optimized sampling-ISR runtime
21 Jul 2011 |
|
Now the pulses of trace #3 are more or less constant ;-)
Much later it came to my mind that calculating _BV(bit) every single time is just stupid, so I distributed the bit shifting to each invocation of the ISR:
static uint8_t bit_value = 1;
if( (bit_value > 0) && (bit_value <= 0x80) ) { // 0x80 = 0b10000000 - read data-bits 0...7
if( (PINA & _BV(PA0)) ) {
soft_uart_rx_byte |= bit_value;
} else {
soft_uart_rx_byte &= ~bit_value;
}
[...]
The compiler is also quite clever in optimizing the first if() statement:
4c4: lds r24, 0x0062
4c8: mov r25, r24
4ca: subi r25, 0x01 ; 1
4cc: sbrc r25, 7
4ce: rjmp .+40 ; 0x4f8
4c4: load 'bit_value' to R24
4c8: move R24 to R25 (to keep R24 safe)
4ca: subtract 1 from R25 <-- this is where the magic happens
4cc: check if BIT7 (MSB) is set in R25, if so SKIP 0x4ce
4ce: jump to 0x4f8
'bit_value' should be a) greater than 0 and b) smaller or equal 128. For an uint8_t that means the following:
a) At least one bit must be set
b) Either the MSB is set, or any combination of the lower bits
Condition a) is almost completely included in b)
Now subtract one.
b) Now only bits 0-6 will be set, bit 7 will have to stay empty !
a) If 'bit_value' started as '0', it would now be 255. the MSB would be set.
The if()-statement is now reduced to a _single_ check if BIT7 is empty.
Optimized ISR runtime - 8th pulse
Optimized ISR runtime - 1st pulse
Jump to top
RSS feed- .:madworm:.'s latest photos with "logic analyzer" - Photos
- ipernity © 2007-2025
- Help & Contact
|
Club news
|
About ipernity
|
History |
ipernity Club & Prices |
Guide of good conduct
Donate | Group guidelines | Privacy policy | Terms of use | Statutes | In memoria -
Facebook
Twitter