From 0453ec88d62335bc317f379188fd9de6a46559f4 Mon Sep 17 00:00:00 2001 From: vintagepc <53943260+vintagepc@users.noreply.github.com> Date: Sat, 18 Jul 2020 16:46:02 -0400 Subject: [PATCH] Fix PCINT on PORTJ for 2560 --- simavr/cores/sim_mega2560.h | 14 ++++++++++++-- simavr/sim/avr_ioport.c | 14 ++++++++++++-- simavr/sim/sim_interrupts.h | 3 +++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/simavr/cores/sim_mega2560.h b/simavr/cores/sim_mega2560.h index 429300f..7e8974c 100644 --- a/simavr/cores/sim_mega2560.h +++ b/simavr/cores/sim_mega2560.h @@ -102,7 +102,17 @@ const struct mcu_t { AVR_IOPORT_DECLARE(f, 'F', F), AVR_IOPORT_DECLARE(g, 'G', G), AVR_IOPORT_DECLARE(h, 'H', H), - AVR_IOPORT_DECLARE(j, 'J', J), + .portj = { + .name = 'J', .r_port = PORTJ, .r_ddr = DDRJ, .r_pin = PINJ, + .pcint = { + .enable = AVR_IO_REGBIT(PCICR, PCIE1), + .raised = AVR_IO_REGBIT(PCIFR, PCIF1), + .vector = PCINT1_vect, + .mask = 0b11111110, + .shift = -1 + }, + .r_pcint = PCMSK1, + }, AVR_IOPORT_DECLARE(k, 'K', K), AVR_IOPORT_DECLARE(l, 'L', L), @@ -353,7 +363,7 @@ const struct mcu_t { .r_tcnt = TCNT2, // asynchronous timer source bit.. if set, use 32khz frequency .as2 = AVR_IO_REGBIT(ASSR, AS2), - + .overflow = { .enable = AVR_IO_REGBIT(TIMSK2, TOIE2), .raised = AVR_IO_REGBIT(TIFR2, TOV2), diff --git a/simavr/sim/avr_ioport.c b/simavr/sim/avr_ioport.c index e35b2de..64adbc4 100644 --- a/simavr/sim/avr_ioport.c +++ b/simavr/sim/avr_ioport.c @@ -153,7 +153,18 @@ avr_ioport_irq_notify( if (p->r_pcint) { // if the pcint bit is on, try to raise it - int raise = avr->data[p->r_pcint] & mask; + int raisedata = avr->data[p->r_pcint]; + uint8_t uiRegMask = p->pcint.mask; + int8_t iShift = p->pcint.shift; + if (uiRegMask) // If mask is 0, do nothing (backwards compat) + raisedata &= uiRegMask; // Mask off + + if (iShift>0) // Shift data if necessary for alignment. + raisedata <<= iShift; + else if (iShift<0) + raisedata >>= -iShift; + + int raise = raisedata & mask; if (raise) avr_raise_interrupt(avr, &p->pcint); } @@ -279,4 +290,3 @@ void avr_ioport_init(avr_t * avr, avr_ioport_t * p) avr_register_io_write(avr, p->r_pin, avr_ioport_pin_write, p); avr_register_io_write(avr, p->r_ddr, avr_ioport_ddr_write, p); } - diff --git a/simavr/sim/sim_interrupts.h b/simavr/sim/sim_interrupts.h index b55ad17..bebf614 100644 --- a/simavr/sim/sim_interrupts.h +++ b/simavr/sim/sim_interrupts.h @@ -42,6 +42,9 @@ typedef struct avr_int_vector_t { avr_regbit_t enable; // IO register index for the "interrupt enable" flag for this vector avr_regbit_t raised; // IO register index for the register where the "raised" flag is (optional) + uint8_t mask; // Mask for PCINTs. this is needed for chips like the 2560 where PCINT do not align with IRQs + int8_t shift; // PCINT8 = E0, PCINT9-15 are on J0-J6. Shift shifts down (<0) or up (>0) for alignment with IRQ#. + // 'pending' IRQ, and 'running' status as signaled here avr_irq_t irq[AVR_INT_IRQ_COUNT]; uint8_t pending : 1, // 1 while scheduled in the fifo -- 2.39.5