Defining the interruption source from I2C0_IRQHandler (KSDK)

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

Defining the interruption source from I2C0_IRQHandler (KSDK)

1,371 Views
matheuspinto
Contributor II

Hello,

 

The I2C0_IRQHandler, generated by kinetis SDK with KDS 3.0.0 and processor expert, can be triggered by differents sources from i2c module.

I want to know, how can I determine when the interrupt corresponds to a complete block write/read, using the I2C_DRV_MasterReceiveData and I2C_DRV_MasterSendData?

I don't want use pooling, e.g. with "I2C_DRV_MasterGetSendStatus".

 

 

Thanks

Labels (1)
0 Kudos
6 Replies

888 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hi PInto,

Which chip do you use ?

There are I2C interrupt demo under KSDK , for k22 example :

\Freescale\KSDK_1.2.0\examples\frdmk22f\demo_apps\i2c_comm\master\kds

or

\Freescale\KSDK_1.2.0\examples\frdmk22f\driver_examples\i2c\i2c_blocking\master\kds

when complete write or read, it will enter void I2C0_IRQHandler(void) , you can run the demo to debug .

Hope it helps

ALice

0 Kudos

888 Views
matheuspinto
Contributor II

Hi Alice,

I am using the kl25z.

I made a test where a flag is set when entering in I2C0_IRQHandler(void).

Another function will pass, just when this flag is set.

To test, if the transfer was really finished, it is used this condition:

if(I2C_DRV_MasterGetReceiveStatus(FSL_I2C_0, &bytesRemaining) == kStatus_I2C_Busy)

{

        redLed_Write(0); // on the LED

        for(;;);

}

What happens is that the program enters in the eternal for(;;), setting the LED.

So I think that the I2C0_IRQHandler(void) is called for another reason beyond the block transfer complete.

0 Kudos

888 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Matheus,

If you doubt the interrupt is not the complete transfer interrupt , i think you can check the interrupt flag :

pastedImage_0.png

Check which interrupt status be set , if there are more than one , you can disable them except the transfer interrupt , then test .

Hope it helps ! 

Alice

0 Kudos

888 Views
matheuspinto
Contributor II

Hi Alice,

Inside the ISR its called the I2C_HAL_GetStopFlag function that returns true if the STOPF bit in I2C_FLT register is set, indicating the presence of a stop bit!

The ISR never enters inside the "else" below!

if(I2C_HAL_GetStopFlag(I2C0_BASE_PTR) != true)

  {

   I2C_DRV_IRQHandler(FSL_I2C_0);
return;

  }

  else

  {

  I2C_DRV_IRQHandler(FSL_I2C_0);
return;

  }

0 Kudos

888 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Matheus,

The STOPF bit indicate the mcu enter stop mode , and whether there have stop signal on I2C bus .

And the function of "I2C_DRV_IRQHandler()" is hardware interrupt , not execute it through software code to judgment .

BR

Alice

0 Kudos

888 Views
matheuspinto
Contributor II

Sorry Alice, but I dont understand what you mean!

The ISR that I am using is the I2C0_IRQHandler, not I2C_DRV_IRQHandler.

Anyway, I think I'm not being understood too. My goal was a mm8451q accel driver using the KSDK. The communication with the accel (write/read his registers) is made with i2c protocol. For this, I create a high level driver for i2c that uses the KSDK i2c driver. My driver was made for projects with or without the FreeRTOS, using macros for this.

The two most importants methods from my i2c driver are:

uint8_t i2c_MasterWrite( const uint8_t * regAddr,

                          uint32_t regAddrSize,

                          const uint8_t * data,

                          uint32_t dataSize,

                          i2c_block_t block);

That function write a block of data in specific register of slave device. If using RTOS, the current task are blocked if block == i2cBLOCKED.

The idea is the same for the function that reads from i2c:

uint8_t i2c_MasterRead( const uint8_t * regAddr,

                                        uint32_t regAddrSize,

                                        uint8_t * data,

                                        uint32_t dataSize,

                                        i2c_block_t block);

A issue occurs when I using the FreeRTOS. When entering in the  i2c_MasterRead the current task (the only one from my test), take the bus acess through a mutex  as shown in figure below, and receives bytes block from i2c bus through I2C_DRV_MasterReceiveData from KSDK. Soon after, the function is blocked by a semaphore , waiting for a signal indicating that all block have been received.

Sem título.png

The i2c_TaskWaitBusTransaction corresponds to a macro:

pastedImage_1.png

Such signal must be indicated ​​by I2C ISR , as shown in the figure below.

pastedImage_7.png

However I was suspected that the interrupt was not triggered only when all the block was sent. So I created a conditional inside the i2c_MasterRead function.

pastedImage_8.png

The goal of this conditional is to indicate through the KSDK API if all bytes were really sent. However, during debugging, my program enters inside the conditional and the actual state of i2c module is Indicated in the figure below.

pastedImage_9.png

Therefore, the ISR is called even when the bus is busy, ie the block was not sent yet!

My project is attached!

Solutions???

0 Kudos