Skip to content

Commit

Permalink
Alternative fix to PR buserror#515- "reverse patch from d2aaebd".
Browse files Browse the repository at this point in the history
PWM output from timer was not modifying the PIN register.
  • Loading branch information
ga committed May 30, 2023
1 parent 7003af0 commit c8bcdc7
Showing 1 changed file with 20 additions and 13 deletions.
33 changes: 20 additions & 13 deletions simavr/sim/avr_ioport.c
Expand Up @@ -155,27 +155,34 @@ avr_ioport_irq_notify(
avr_t * avr = p->io.avr;

int output = value & AVR_IOPORT_OUTPUT;
value &= 0xff;
uint8_t mask = 1 << irq->irq;
uint8_t ddr = avr->data[p->r_ddr];
uint8_t new_pin;

value &= 0xff;
new_pin = (avr->data[p->r_pin] & ~mask) | (value ? mask : 0);
if (output) {
if ((mask & ddr) == 0)
return; // TODO: stop further processing of IRQ.

// If the IRQ was marked as Output, also do the IO write.
uint8_t new_out;

new_out = (avr->data[p->r_port] & ~mask) | (value ? mask : 0);
if (mask & ddr) {
// If the IRQ was marked as Output, do the IO write.

avr_ioport_write(avr, p->r_port, new_out, p);
avr_core_watch_write(avr, p->r_pin, new_pin);
} else {
/* Set the PORT register so the output will be visible
* when the corresponding DDR bit is set.
* Real hardware does not do this.
*/

avr_ioport_write(avr,
p->r_port,
(avr->data[p->r_port] & ~mask) |
(value ? mask : 0),
p);
avr->data[p->r_port] = new_out;
return; // TODO: stop further processing of IRQ.
}
} else {
// Set the real PIN bit. Ignore DDR as it's masked when read.

avr_core_watch_write(avr, p->r_pin,
(avr->data[p->r_pin] & ~mask) |
(value ? mask : 0));
avr_core_watch_write(avr, p->r_pin, new_pin);

/* BUG: If DDR bit is set here, there should be no
* interrupt. But a spurious IRQ call by the user
Expand Down

0 comments on commit c8bcdc7

Please sign in to comment.