Setting PRIMASK register(CyEnterCriticalSection) in I2C slave low power mode(CySysPmDeepSleep) for PSoC4000S

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

cross mob
YoIs_1298666
Level 5
Level 5
250 sign-ins 100 replies posted 100 sign-ins

Hello,

We can see the sample code for the low power mode in PSoC 4 Serial Communication Block (SCB) datasheet.

According to this, it is recommended to set the PRIMASK register using CyEnterCriticalSection before entering CySysPmDeepSleep. However, even in CySysPmDeepSleep, CyEnterCriticalSection is used to set the PRIMASK register. In other words, the PRIMASK register is set twice.

 

Is it okay to recognize that the PRIMASK register is set with "uint8 intState = CyEnterCriticalSection();  ...................... (1)" and cleared with ”CyExitCriticalSection(interruptState);  ...................... (4)"?

Please see the code below.

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

/* Enter critical section to lock the slave state */
uint8 intState = CyEnterCriticalSection();  ...................... (1)
/* Check if slave is busy */
status = (SCB_I2CSlaveStatus() & (SCB_I2C_SSTAT_RD_BUSY | SCB_I2C_SSTAT_WR_BUSY));
if (0u == status)
{
    /* Slave is not busy: enter Deep Sleep */
    SCB_Sleep(); /* Configure the slave to be wakeup source */
    CySysPmDeepSleep();

    /* Exit critical section to continue slave operation */
    CyExitCriticalSection(intState);   ...................... (2)
    SCB_Wakeup(); /* Configure the slave to active mode operation */
}
else
{
    /* Slave is busy. Do not enter Deep Sleep. */
    /* Exit critical section to continue slave operation */
    CyExitCriticalSection(intState);
}

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

void CySysPmDeepSleep(void)
{
    uint8 interruptState;

   ........

    interruptState = CyEnterCriticalSection();  ...................... (3)

   ........

    CyExitCriticalSection(interruptState);  ...................... (4)
}

 

Best regards,

Yocchi 

0 Likes
1 Solution
AikoO_51
Moderator
Moderator
Moderator
100 sign-ins First question asked 50 solutions authored

 CyEnterCriticalSection() is to disable interrupts, and CyExitCriticalSection() is to enable interrupts.

It's needed to disable interrupts before getting the status of I2C in the user's code(main.c), and then it's also needed to call again because it's in the system operation code. (CySysPmDeepSleep())

Aiko Ohtaka
Infineon Technologies

View solution in original post

0 Likes
3 Replies
AikoO_51
Moderator
Moderator
Moderator
100 sign-ins First question asked 50 solutions authored

 CyEnterCriticalSection() is to disable interrupts, and CyExitCriticalSection() is to enable interrupts.

It's needed to disable interrupts before getting the status of I2C in the user's code(main.c), and then it's also needed to call again because it's in the system operation code. (CySysPmDeepSleep())

Aiko Ohtaka
Infineon Technologies
0 Likes

Hello Aiko-san,

Thank you very much for your reply.

There is the explanation of CriticalSection in "cy_boot Component v5.80
Document Number: 002-25675 Rev. **".

So I will ask you the first question again.

I am debugging it now.  It seems that it is setting with "uint8 intState = CyEnterCriticalSection();  ...................... (1)" and is clearing with ”CyExitCriticalSection(interruptState);  ...................... (2)".

YoIs_1298666_0-1642410976352.png

Best regards,

Yocchi

0 Likes

Yes, your understanding is correct.

Aiko Ohtaka
Infineon Technologies
0 Likes