Interrupt misconception on Due (ATSAM3X)

I'm experimenting with the non-blocking I2C (TWI) after reading this post, I have a few questions.

It seems like:

  1. A enabled interrupt (IER) will prevent TWI from starting communication
  2. Two Wire Interface (TWI) aka I2C will resume if you disable those pre-enabled interrupt
  3. PDC (peripheral DMA) will not work with only 1 byte of data. (I still need to confirm this)

This will work

WIRE_INTERFACE->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS;	// set master mode
WIRE_INTERFACE->TWI_MMR = TWI_MMR_DADR(dev_addr) | TWI_MMR_IADRSZ_NONE;
WIRE_INTERFACE->TWI_CR = TWI_CR_STOP;		// set stop for one byte
WIRE_INTERFACE->TWI_THR = (*data_ptr);		// start the transmission
WIRE_INTERFACE->TWI_IER = TWI_IER_TXCOMP | TWI_IER_NACK;	// interrupt enable register *after* tx begins

This will cause ISR to fire rapidly, with TXRDY and TXCOMP flag both "true". No signal on the line (monitored by oscilloscope)

WIRE_INTERFACE->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS;	// set master mode
WIRE_INTERFACE->TWI_MMR = TWI_MMR_DADR(dev_addr) | TWI_MMR_IADRSZ_NONE;
WIRE_INTERFACE->TWI_IER = TWI_IER_TXCOMP | TWI_IER_NACK;	// interrupt enable register 
WIRE_INTERFACE->TWI_CR = TWI_CR_STOP;		// set stop for one byte
WIRE_INTERFACE->TWI_THR = (*data_ptr);		// start the transmission

However, the tx will resume as soon as you called WIRE_INTERFACE->TWI_IDR = WIRE_INTERFACE -> TWI_IMR;

My question is:

  1. What is the triggering point of an ISR like this? Rising edge? Falling edge? A "true" bit? A change in bit?
  2. This behavior of rapidly fired ISR seems like a bug to me? Is there any explanation?
  3. Anyone get the PDC to work with only 1-byte transmission?

p.s. I'll gladly provide complete code if it's needed. It's a mess right now, I'm quite firmative that other stuff isn't related.

Sounds like you aren’t resetting the interrupt cause in the isr. On AVR, that’ll happen automatically when you read the data (or something) but some peripherals on some chips need an explicit command to tell it that the interrupt has been serviced. I’m afk at the moment, and can’t check whether the sam3x is one of these or not, but it’s something to look into...

You can find several example sketches with a direct register prgramming for TWI0(SDA1/SCL1) and TWI1(SDA/SCL), e.g. this one (reply #2):

You should try to fully understand this type of example sketch before moving the code to a PDC DMA.

westfw:
Sounds like you aren’t resetting the interrupt cause in the isr. On AVR, that’ll happen automatically when you read the data (or something) but some peripherals on some chips need an explicit command to tell it that the interrupt has been serviced. I’m afk at the moment, and can’t check whether the sam3x is one of these or not, but it’s something to look into...

I did disabled all the interrupts whenever I can if that's what you're talking about (don't think so)

Curretly, it does seems like the interrupt will fire whenever the target bits is "true" (but some cases are edgy as far as I could tell).

Another issue is that I'll have to read the Status Register by myself which feels quite weird. I thought there should be some kind of flag that marks the reason of this interrupt?

Here's the manual I'm using, it is really vague for a newbie like me.

ard_newbie:
You can find several example sketches with a direct register prgramming for TWI0(SDA1/SCL1) and TWI1(SDA/SCL), e.g. this one (reply #2):
The transfer could not be performed due to a clock stretch timeout (-2147024775) - Arduino Due - Arduino Forum
You should try to fully understand this type of example sketch before moving the code to a PDC DMA.

Actually that's exeactly what I did (or at least tried)! My workspace includes a working version using Wire library directly from the \sam\1.6.12\libraries. The Wire library just pools on the status register so the case is somewhat different.

Thanks for the pointer to the post, still. I'll read it again and see if I've missed anything few days ago.

EDIT: Here is a working prototype that doesn't seems to have too much of an issue: GitHub - EwingKang/Non-blocking-MPU9250-Arduino-Due-DMP-IMU-Driver: An Arduino Due prototype that uses PDC on I2C communication with GY85 9-axes MEMS