CySysLvdEnable causes issue for I2C write.

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
NeDh_4602711
Level 5
Level 5
5 solutions authored First solution authored 50 replies posted

Hello,

I have started using LVD after this Click here.

I am using the CYBLE-0220001-00 module in PSoC creator 4.3. Whenever CySysLvdEnable(CY_LVD_THRESHOLD_3_20_V) is called and after I2C_1_I2CMasterWriteBuf(address, (uint8_t *)Write_Buf, sizeof(Write_Buf), I2C_1_I2C_MODE_COMPLETE_XFER) is called then it causes hang. but instead of I2C_1_I2C_MODE_COMPLETE_XFER if I2C_1_I2C_MODE_NO_STOP is used the it works fine. If I still want to use I2C_1_I2C_MODE_COMPLETE_XFER then I have to first call CySysLvdDisable() before I2C write function.

Could u please tell me what can be the problem?

Thanks and regards,

Neeraj

0 Likes
1 Solution

It is not recommended  to call CyDelay(3000u); within the ISR since it will prevent other important interrupts to be serviced. Since I2C is interrupt driven, this LVD interrupt could be completely masking the I2C interrupt if the priority of i2c interrupt is less than lvd interrupt.

It is better you raise a flag in the LVD interrupt and handle the GPIO high - low related code in your main function by polling the flag in the main loop.

CY_ISR(PwrIsrHandler)

{

    /* Clear Interrupt */

   isr_Pwr_ClearPending();

    CySysLvdClearInterrupt();

   lvd_flag = 1;

}

main()

{

..

if(lvd_flag)

{

     toggle pin

     lvd_flag = 0;

}

}

Can you try this?

Regards,
Bragadeesh

View solution in original post

0 Likes
12 Replies
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi NeDh_4602711​,

1. Would it be possible for you to share your project file with us so that we can find the root cause of this issue? Please use the following link to archive your project and send it to us

Archiving a PSoC Creator Design

2. Please share with us the schematic of the design.

3. Please attach the debugger and share us the call stack when the issue occurs.

4. Probe the I2C bus in both the cases and compare the waveform.

5. Please check if you are seeing LVD low voltage event.

Best regards,

Bragadeesh

Regards,
Bragadeesh
0 Likes

Hello BragadeeshV_41​,

Thanks for your reply.

Is it possible for you to take access of my computer to check what you want?

Thanks and regards,

Neeraj

0 Likes

Hi NeDh_4602711​,

Please share your project as suggested in the previous response so that we can debug your project at my end. Unfortunately it may not be possible to do an remote session in this community support.

Regards

Bragadeesh

Regards,
Bragadeesh
0 Likes

Hello,

I hope from the below clue you may understand my problem.

I was checking the circuit on my PCB and found the above problem, but when I connect my sensor directly to CY8Ckit-042-BLE with CYBLE-022001-00 EVAL board then it works perfectly without any hang issue.

Could you please tell me hint what can be the issue. I just connected SDA and SCL pins nothing else than this.

Is there anything else circuit present in CY8Ckit-042-BLE which I am missing to consider in my PCB? because the same code I am using in this EVAL board.

pastedImage_0.pngpastedImage_1.pngpastedImage_4.png(1)pastedImage_0.png(2)

In the attached Circuit diagram (1) SDA and SCL tracks are highlighted in violet color.

Thanks and regards,

Neeraj Dhekale

0 Likes

Did you register an ISR to deal with the LVD?

My guess is there is something going on with the interaction between the I2C interrupt and the LVD interrupt

What are you trying to do with the LVD?

Alan

0 Likes

Hello Alan,

Replying to your question.

Did you register an ISR to deal with the LVD?

Yes I have registered

//The interrupt handler for Low Voltage Detect interrupts.

CY_ISR(PwrIsrHandler)

{

    /* Clear Interrupt */

   isr_Pwr_ClearPending();

    CySysLvdClearInterrupt();

    low_battery =1;

    //LED_LowVoltage_Write(LIGHT_ON);

    CyDelay(3000u);

    //LED_LowVoltage_Write(LIGHT_OFF);

    low_battery=0;

    CyDelay(3000u);

    low_battery =1;

}

when low_battery=1 I am showing low battery symbol on OLED screen on a wristband.

pastedImage_1.png

My guess is there is something going on with the interaction between the I2C interrupt and the LVD interrupt

What are you trying to do with the LVD?

I have written firmware for a wristband which has MAX30100 sensor to check heart rate and SPO2 of the user and I am trying to detect LOW Battery on LVD trigger event suggested me here and I have set a threshold to CY_LVD_THRESHOLD_3_20_V using CySysLvdEnable(CY_LVD_THRESHOLD_3_20_V);

Regards,

Neeraj

0 Likes

It is not recommended  to call CyDelay(3000u); within the ISR since it will prevent other important interrupts to be serviced. Since I2C is interrupt driven, this LVD interrupt could be completely masking the I2C interrupt if the priority of i2c interrupt is less than lvd interrupt.

It is better you raise a flag in the LVD interrupt and handle the GPIO high - low related code in your main function by polling the flag in the main loop.

CY_ISR(PwrIsrHandler)

{

    /* Clear Interrupt */

   isr_Pwr_ClearPending();

    CySysLvdClearInterrupt();

   lvd_flag = 1;

}

main()

{

..

if(lvd_flag)

{

     toggle pin

     lvd_flag = 0;

}

}

Can you try this?

Regards,
Bragadeesh
0 Likes

Hi BragadeeshV_41​,

Thank you so much.

After removing of CyDelay(); it works fine now. But just for my understanding, I am happy but still confused. why it was working well on PSOC baseboard and not in my PCB. This CyDelay(_) is used in your VoltageDetect_PSoC4 Example code. which works fine in baseboard but not in PCB.

Anyway, Thank you so much.

Regards,

Neeraj

0 Likes

When you run CyDelay the CPU goes into a busy wait loop.... basically you end up with an assembly language loop that count a certain number of cycles and runs a nop.

If you put this in a ISR it will lock the CPU so that it cannot respond to any other Interrupts... unless they are higher priority.

The Bluetooth and the I2C both depend on interrupts.

What is happening is that the lvd is triggering that interrupt.. then the I2C interrupt is being triggered... but does not get serviced until the LVD interrupt has finished... by that time the thing that happened on I2C is over and you have MISSED it.

Why is it different between the two boards?  It has to be that the other board isn't triggering the interrupt... which means that the LVD is not getting triggered.  I suppose the other possibility is that the other I2C happens at a time when it doesn't collide with the LVD interrupt.

Alan

I try not to be dogmatic about software.... however, mostly you should never use a CyDelay

But...

REALLY NEVER EVER NEVER EVER NEVER NEVER PUT A CYDELAY IN AN ISR

Alan

Hello AlanH_86​,

Noted. Not to use never ever CyDelay in ISR.

I understood where I was wrong.

Thank you so much.

Regards,

Neeraj

0 Likes

I am almost positive that this has absolutely nothing to do with the board layout.... and that it has something to do with your firmware.

Notice that Bragadeesh asked for the firmware... that is what is going to be required to sort this out.

Alan

0 Likes