How to use LPI2C in transfer mode in i.MX RT

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

How to use LPI2C in transfer mode in i.MX RT

Jump to solution
2,269 Views
Maciek
Contributor V

Hi, I have a question about the intended usage of the I2C driver block.

1. I2C block in Transfer mode uses interrupts in the background and we do not need to configure interrupts or use interrupts blocks during I2C transfer. Am I right ?

2. The state machine responsible for handling all the steps/stages of the 'transfer process' is implemented somewhere in the ISRs and the whole transfer process may take significant time - for example greater than the model step. I assume that by using the block for example, in a function call or triggered subsystem we only initiate the transfer process and then the transfer callback will be called automatically at the end of the transfer. Am I right ?

3. When we try to use multiple LPI2C_Data_Transfer blocks (for example, one 'write' block to configure the registers in some I2C device, and one 'read' block to read data from that device) - in the generated code we see LPI2C_Master_Callback function duplicated and such code doesn't compile. Why is this duplication happening ? What is the proper way to use this block in the model (can we use more than one block) ?

4. How can I create a model that, for example, at one time sets a time and date in external RTC (the 'write' transfer) and at another time reads the time and date from RTC (the 'read' transfer) ? What is the intended workflow in such scenario ?

5. It would be better to have more elaborated examples - the I2C examples from the toolbox don't tell/show much...

Thanks for help
Maciek

0 Kudos
1 Solution
2,248 Views
nxa11767
NXP Employee
NXP Employee

Hi @Maciek ,

1,2. Yes, the transfer method is using interrupts in the background and the callback function is called by the interrupt handler when the transfer is completed. The interrupt handler in transfer mode is being defined in the fsl_lpi2c.c source in the SDK.

3. We are aware of this issue/limitation. We plan a refactorization of the LPI2C blocks - the transfer callback output on master mode will be removed from the transfer block and will translate in a separate block - the transfer function callback is unique per LPI2C instance. (I will keep you updated on this). Till then I've attached a fix (more of an workaround honestly) for the compilation error. You should connect to just one block a function call subsystem for the transfer callback and for the rest of the blocks use terminator for the transfer callback output. Unzip the attached in <toolbox_path>\mbdtbx_imxrt\blocks\lpi2c.

4. In this case you can use the blocking method - for e.g write in a blocking mode the data, and after write is finished you can do the read in non-blocking mode for e.g (the I2C blocking write function will not return till the data was send with success). Additionally you can use flags to signal when the transfer is completed (set up the flag in the function callback). Also you can check the transfer status output of the transfer block - when a I2C transfer is in progress the transfer status will be kStatus_LPI2C_Busy (900) or 0 for kStatus_Success (0).

5. We are aware that the examples are very basic. For the next update of the toolbox we are targeting to extend the examples. We did something more complex on DSC toolbox for I2C communication - to configure and communicate with an FXOS8700CQ accelerometer. You can take a look at that model application.

 

Best regards,

Alexandra

View solution in original post

0 Kudos
3 Replies
2,249 Views
nxa11767
NXP Employee
NXP Employee

Hi @Maciek ,

1,2. Yes, the transfer method is using interrupts in the background and the callback function is called by the interrupt handler when the transfer is completed. The interrupt handler in transfer mode is being defined in the fsl_lpi2c.c source in the SDK.

3. We are aware of this issue/limitation. We plan a refactorization of the LPI2C blocks - the transfer callback output on master mode will be removed from the transfer block and will translate in a separate block - the transfer function callback is unique per LPI2C instance. (I will keep you updated on this). Till then I've attached a fix (more of an workaround honestly) for the compilation error. You should connect to just one block a function call subsystem for the transfer callback and for the rest of the blocks use terminator for the transfer callback output. Unzip the attached in <toolbox_path>\mbdtbx_imxrt\blocks\lpi2c.

4. In this case you can use the blocking method - for e.g write in a blocking mode the data, and after write is finished you can do the read in non-blocking mode for e.g (the I2C blocking write function will not return till the data was send with success). Additionally you can use flags to signal when the transfer is completed (set up the flag in the function callback). Also you can check the transfer status output of the transfer block - when a I2C transfer is in progress the transfer status will be kStatus_LPI2C_Busy (900) or 0 for kStatus_Success (0).

5. We are aware that the examples are very basic. For the next update of the toolbox we are targeting to extend the examples. We did something more complex on DSC toolbox for I2C communication - to configure and communicate with an FXOS8700CQ accelerometer. You can take a look at that model application.

 

Best regards,

Alexandra

0 Kudos
2,242 Views
Maciek
Contributor V

Hi @nxa11767 

thanks for the quick response. 

Questions about your response 3:
I assume that with your fix we should be able to set as many 'transfer read/write' blocks as we want.
Only one block will have transfer callback connected to 'function call subsystem' (rest of the blocks will have terminators) and this subsystem should have all the code for all the possible callback actions used in the whole model.
This means that wherever we use transfer block (to initiate read or write transfer) in the model we also should have some mechanism (like global variable or message,etc.) to inform the subsystem with the callback: what actually should be done at the end of this particular transmission. The whole callback (function call subsystem) will be run in the context of the ISR (not in the model step).
Am I right with the above ?

Question about your response 4:
I don't understand your suggestion: how can we mix blocking and non-blocking (transfer) modes in one model (at least without using custom code) ? The mode of the LPI2C block is 'sucked in' from the generated code configured in Config Tools!
I assume that you suggest using transfer status flags as an alternative for using transfer callback - this way we can move all the code needed after transfer completion into the model step (execution not in ISR).
Am I right with the above ?

Additional question:
Do I understand correctly: that we need to assure that we don't initiate multiple transfers at the same time in the model (the LPI2C block in transfer mode must be triggered/called only after the previous transmission has ended) ?

Thanks

Maciek

 

0 Kudos
2,217 Views
nxa11767
NXP Employee
NXP Employee

Hi @Maciek ,

See my responses below.

1. Yes, with the fix, will be able to set multiple transfer blocks for i2c master and just one callback function block that will deal with the transfer complete interrupt. 

"This means that wherever we use transfer block (to initiate read or write transfer) in the model we also should have some mechanism (like global variable or message,etc.) to inform the subsystem with the callback: what actually should be done at the end of this particular transmission."  -> yes, you are correct - you should use a mechanism to notify the completion of the transfer. 

"The whole callback (function call subsystem) will be run in the context of the ISR (not in the model step)." -> correct

2. My mistake here, I had DSC toolbox in mind, where Config Tool support is different and there we had a slightly different design for the transfer block.

The alternative solution for IMXRT, is indeed to check the transfer status flag, and not proceed to the next action till the particular transfer is done.

3. If a transfer is already in progress, then a new i2c transfer will exit with a status flag of Busy - will not be initiated. (by SDK function design, see here more details). The model should have some kind of mechanism to synchronize multiple i2c transfers.

 

Best regards,

Alexandra

0 Kudos