Conflict between I2C and PIT modules

cancel
Showing results for 
Search instead for 
Did you mean: 

Conflict between I2C and PIT modules

187 Views
Contributor III

Hi,

I am using the FRDM-K64F board and MCUXpresso, and I am trying to read accelerometer data through I2C module.

The goal of my project is to read data from the accelerometer every 20 ms. For this, I configure the PIT module to interrupt every 20 ms and within its interrupt controller I call the functions to read the accelerometer data.

If I configure the I2C module to acquire accelerometer data without using the PIT module, I can receive data fine.

But when I add the PIT module code and put the code to read the accel data inside the PIT interrupt handler, the program is stuck on the I2C data reading functions, particularly in the following line inside I2C_ReadAccelRegs:

while ((!nakFlag) && (!completionFlag)){}

Can you give me some clue about this problem?

Thanks in advance.

Best regards.

EDIT: I attach my project compressed in zip format.

Labels (1)
3 Replies

20 Views
NXP TechSupport
NXP TechSupport

Hello Leandro,

Hope you are doing well.

Could you please provide the modifications you made to the example with the pit handler as well. So I can try to reproduce it from my end and check it with detail. If possible please provide it as an attachment on this thread.

Also can you confirm the IDE and SDK version you are using please.

Best Regards,

Sabina

-----------------------------------------------------------------------------------------------------------------------

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

----------------------------------------------------------------------------------------------------------------------- 

0 Kudos

20 Views
Contributor III

Hi Sabina Bruce, thanks for your quick answer.

I attached the zip file of my project that presents the mentioned problems.

The steps I followed are the following:

1) I added the PIT drivers (fsl_pit.h, fsl_pit.c) to the project and I included them in the code.

2) I created a function to initialize PIT module:

void Initialize_PIT(void)
{
    pit_config_t pitConfig;
    pitConfig.enableRunInDebug = true;
    PIT_GetDefaultConfig(&pitConfig);
    /* Init pit module */
    PIT_Init(PIT, &pitConfig);
    /* Set timer period for channel 0 */
    PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, USEC_TO_COUNT(20000U, PIT_SOURCE_CLOCK));
    /* Enable timer interrupts for channel 0 */
    PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable);
    /* Enable at the NVIC */
    EnableIRQ(PIT_IRQ_ID);
    /* Start channel 0 */
    PRINTF("\r\nStarting channel No.0 ...");
    PIT_StartTimer(PIT, kPIT_Chnl_0);
}


3) I added definitions and the handler for PIT module, and I put the code to read accel data inside PIT handler:

#define PIT_LED_HANDLER PIT0_IRQHandler
#define PIT_IRQ_ID PIT0_IRQn
#define PIT_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk)



void PIT_LED_HANDLER(void)
{
    uint8_t readBuff[7];
    uint32_t i            = 0U;
    uint8_t status0_value = 0;
    int16_t x, y, z;
    for (i = 0; i < ACCEL_READ_TIMES; i++)
    {
        status0_value = 0;
        /*  wait for new data are ready. */
        while (status0_value != 0xff)
        {
            I2C_ReadAccelRegs(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, ACCEL_STATUS, &status0_value, 1);
        }


        /*  Multiple-byte Read from STATUS (0x00) register */
        I2C_ReadAccelRegs(BOARD_ACCEL_I2C_BASEADDR, g_accel_addr_found, ACCEL_STATUS, readBuff, 7);


        status0_value = readBuff[0];
        x             = ((int16_t)(((readBuff[1] * 256U) | readBuff[2]))) / 4U;
        y             = ((int16_t)(((readBuff[3] * 256U) | readBuff[4]))) / 4U;
        z             = ((int16_t)(((readBuff[5] * 256U) | readBuff[6]))) / 4U;


        PRINTF("status_reg = 0x%x , x = %5d , y = %5d , z = %5d \r\n", status0_value, x, y, z);
    }
    /* Clear interrupt flag.*/
    PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag);
    __DSB();
}


4) In the main function, I add the initialization function for PIT module:

Initialize_PIT();


5) I comment out the lines of the main function that read the acceleration data, due to these functions are used inside PIT handler instead of main function.

The code is stuck always in the following line of I2C module:

while ((!nakFlag) && (!completionFlag)){}


Thanks,
Best regards.

0 Kudos

20 Views
NXP TechSupport
NXP TechSupport

Hello Leandro,

Hope you are doing well.

I have tested this from my end with no problem. However, I did make a few modifications. 

First, some good practices when doing interrupts is that within the handler try to keep it to a minimum. This will help speed things up and simplify what is occurring, so try to only use flags in a handler instead of a whole function that calls others. This is because it might be too fast that by the time the interrupt is triggered again you haven't finished requesting the data from I2C module. 

Basically, what I did is I took the original example from our SDK for i2c_read_accel_value_transfer and the pit and merged them. 

I took the i2c code that prints the values and placed it inside the main while loop and added a flag so it only enters when the pit flag is enabled.

pastedImage_1.png

In my pit handler I added this flag so it enables it every 20ms. 

pastedImage_2.png

I also added the original led function from the pit example of the SDK in the while loop so I know that the pit is actually working.

pastedImage_3.png

You can try first with the pit configuration that is 1 second and then change it to your desired time. Could you please try it like this and see if it works the same for you?

Best Regards,

Sabina

-----------------------------------------------------------------------------------------------------------------------

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

-----------------------------------------------------------------------------------------------------------------------