Package: simavr
Version: 1.6+dfsg-3
Severity: normal
Tags: patch fixed-upstream

In simavr 1.6, avr_adc_t stores only 8 ADC input values (uint16_t
adc_values[8] in sim/avr_adc.h), and the ADC input IRQ handler only accepts
ADC_IRQ_ADC0..ADC7 (sim/avr_adc.c). On parts with 16 ADC channels, such as
the ATmega2560, analog inputs 8..15 are therefore ignored when set, and a
conversion on them reads past the end of adc_values[], which returns
garbage.

Example: setting ADC0..ADC15 to 100 mV * (n+1) and reading them with
analogRead() in a firmware running on a simulated ATmega2560 gives A0..A7 =
20, 40, 61, 81, 102, 122, 143, 163 (correct), but A8..A15 = 0, 0, 0, 0,
1023, 99, 1023, 0.

Upstream fixed this in 2020:
https://www.google.com/url?q=https://github.com/buserror/simavr/commit/73ae11a0b0&source=gmail&ust=1791157240645000&sa=E
("Fix ADCs>7"), released in simavr v1.7 and v1.8. Please update the
package, or backport the fix. The minimal patch below (also attached) makes
adc_values[] 16 entries long and lets the handler accept ADC_IRQ_ADC0 ...
ADC_IRQ_ADC15. Built from the 1.6+dfsg-3 source on Debian trixie (amd64),
it fixes the example above: all 16 inputs read correctly.

--- a/simavr/sim/avr_adc.h
+++ b/simavr/sim/avr_adc.h
@@ -135,7 +135,7 @@
* runtime bits
*/
avr_adc_mux_t muxmode[64];// maximum 6 bits of mux modes
- uint16_t adc_values[8]; // current values on the ADCs
+ uint16_t adc_values[16]; // current values on the ADCs (16: ATmega2560
has ADC8..ADC15)
uint16_t temp; // temp sensor reading
uint8_t first;
uint8_t read_status; // marked one when adcl is read
--- a/simavr/sim/avr_adc.c
+++ b/simavr/sim/avr_adc.c
@@ -273,7 +273,7 @@
avr_t * avr = p->io.avr;

switch (irq->irq) {
- case ADC_IRQ_ADC0 ... ADC_IRQ_ADC7: {
+ case ADC_IRQ_ADC0 ... ADC_IRQ_ADC15: {
p->adc_values[irq->irq] = value;
} break;
case ADC_IRQ_TEMP: {

This report was prepared by Claude, an AI assistant, on behalf of Kevin
Boergens, who asked for it to be sent. The bug and the fix were checked by
building and running the patched library.

Thanks for maintaining simavr in Debian.
ATmega2560 (and other parts with ADC8..ADC15): avr_adc_t stored only 8 input values and the input IRQ
handler accepted only ADC0..ADC7, so analog inputs 8..15 read past adc_values[] (garbage).

--- a/simavr/sim/avr_adc.h
+++ b/simavr/sim/avr_adc.h
@@ -135,7 +135,7 @@
 	 * runtime bits
 	 */
 	avr_adc_mux_t	muxmode[64];// maximum 6 bits of mux modes
-	uint16_t		adc_values[8];	// current values on the ADCs
+	uint16_t		adc_values[16];	// current values on the ADCs (16: ATmega2560 has ADC8..ADC15)
 	uint16_t		temp;		// temp sensor reading
 	uint8_t			first;
 	uint8_t			read_status;	// marked one when adcl is read
--- a/simavr/sim/avr_adc.c
+++ b/simavr/sim/avr_adc.c
@@ -273,7 +273,7 @@
 	avr_t * avr = p->io.avr;
 
 	switch (irq->irq) {
-		case ADC_IRQ_ADC0 ... ADC_IRQ_ADC7: {
+		case ADC_IRQ_ADC0 ... ADC_IRQ_ADC15: {
 			p->adc_values[irq->irq] = value;
 		} 	break;
 		case ADC_IRQ_TEMP: {

Reply via email to