I2C DMA Slave Transmitter

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C DMA Slave Transmitter

Jump to solution
2,499 Views
martinleclerc
Contributor II

I am trying to improve the performance of my I2C slave driver by using the DMA mode.

The board is design with a KL17 MCU.

 

When the I2C Slave is transmitting data, the DMA option 'Cycle-Steal' is activated.

And when the DMA channel counter reach zero, an interrupt is generated.

So far it's working as expected.

 

But the Slave doesn’t know in advance how many data bytes are to be transmitted to the master device.

And all the regular I2C interrupt seems to be disabled when the DMA is activated with the mode 'Cycle-Steal'.

 

Is it possible to have an interrupt to detect the end of transfer (NAK) when the 'Cycle Steal' mode is activated ?

 

The only solution I found so far is by polling the I2C status register for RXAK with a While loop.

I want to free my CPU as much as possible, this is why the polling mechanism is not a good solution.

Labels (1)
0 Kudos
1 Solution
1,429 Views
martinleclerc
Contributor II

Having random length transfers on a slave serial communications peripheral will make using the DMA challenging.  The I2C peripheral can generate either an interrupt or a DMA service request, but not both.  I have discussed this scenario with several other engineers in the past.  The most common resolution involves linking a second DMA channel that is configured to reset a hardware timeout.

As an example, the Low Power Timer (LPTMR) can be configured to function as this I2C timeout by setting up its prescale and compare registers accordingly.  The LPTMR’s counter is reset when it’s disabled, counts up when it’s enabled and can generate an interrupt when the counter’s value equals that of its compare register.  The second DMA channel can be configured to perform sequential transfers (i.e., continuous operation, not cycle-steal) to the LPTMR’s Control Status Register that will disable it (thereby resetting the counter) and then re-enable it.  Once there is a long enough pause by the I2C master – i.e., I2C transfers have stopped – the LPTMR will generate an interrupt indicating that the transfer is finished.

This technique relies upon knowing that the I2C transfers are continuous and that a proper timeout value can be used.

Please let me know if this helps.

Best Regards,

Derrick

View solution in original post

0 Kudos
3 Replies
1,430 Views
martinleclerc
Contributor II

Having random length transfers on a slave serial communications peripheral will make using the DMA challenging.  The I2C peripheral can generate either an interrupt or a DMA service request, but not both.  I have discussed this scenario with several other engineers in the past.  The most common resolution involves linking a second DMA channel that is configured to reset a hardware timeout.

As an example, the Low Power Timer (LPTMR) can be configured to function as this I2C timeout by setting up its prescale and compare registers accordingly.  The LPTMR’s counter is reset when it’s disabled, counts up when it’s enabled and can generate an interrupt when the counter’s value equals that of its compare register.  The second DMA channel can be configured to perform sequential transfers (i.e., continuous operation, not cycle-steal) to the LPTMR’s Control Status Register that will disable it (thereby resetting the counter) and then re-enable it.  Once there is a long enough pause by the I2C master – i.e., I2C transfers have stopped – the LPTMR will generate an interrupt indicating that the transfer is finished.

This technique relies upon knowing that the I2C transfers are continuous and that a proper timeout value can be used.

Please let me know if this helps.

Best Regards,

Derrick

0 Kudos
1,429 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Martin Leclerc:

There is not an interrupt to detect the reception of NAK, but there is an interrupt for the detection of the I2C bus STOP condition. Would that work for you?

I suppose your I2C master device would trigger the stop signal when receiving the last byte expected from the KL17 slave.


Regards!,
Jorge Gonzalez

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,429 Views
martinleclerc
Contributor II

Hello Jorge, The I2C bus STOP condition is exactly the solution that I am looking for.

I can confirm that when I2C interrupt are enabled, the STOP condition is detected properly.

I am also able to detect all other interrupts like START, TCF (Transfer Complete), ...

But, when the DMA interrupt is activated with the mode `Cycle Steal`

the only interrupt generated is when the DMA channel counter reach zero.

All other I2C interrupts including the STOP condition are not generated.

My main suspect is the mode "Cycle Steal".

It looks like this mode can be used only when you know exactly the length (number of bytes) to be transmitted.

Otherwise it's not a good solution when you don't know in advance how many bytes are to be transmitted.

Please let me know if you have any suggestion.

thanks,

Martin

0 Kudos