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),
.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),
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);
}
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);
}
-
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