Is Cy_SysLib_EnterCriticalSection() documented?

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

cross mob
CaKu_4284131
Level 5
Level 5
50 replies posted 25 replies posted 10 likes received

I'm looking at this:

__STATIC_INLINE void Cy_RTC_SyncFromRtc(void)

{

    uint32_t interruptState;

   

    interruptState = Cy_SysLib_EnterCriticalSection();

   

    /* RTC Write is possible only in the condition that CY_RTC_BUSY bit = 0

    *  or RTC Write bit is not set.

    */

    if ((CY_RTC_BUSY != Cy_RTC_GetSyncStatus()) && (!_FLD2BOOL(BACKUP_RTC_RW_WRITE, BACKUP_RTC_RW)))

    {

        /* Setting RTC Read bit */

        BACKUP_RTC_RW = BACKUP_RTC_RW_READ_Msk;

        /* Delay to guarantee RTC data reading */

        Cy_SysLib_DelayUs(CY_RTC_DELAY_WHILE_READING_US);

        /* Clearing RTC Read bit */

        BACKUP_RTC_RW = 0U;

    }

    Cy_SysLib_ExitCriticalSection(interruptState);

}

in Generated_Source\PSoC6\pdl\drivers\peripheral\rtc\cy_rtc.h. I'm guessing that Cy_SysLib_EnterCriticalSection() disables interrupts and returns the previous value.  If so, is it really necessary for this function to disable interrupts the whole time? It really messes with my application. Could I make my own version of this routine that wouldn't block interrupts for so long? (I don't really understand exactly how this routine works.)

0 Likes
1 Solution
VenkataD_41
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hi,

When you are executing some important block of code which should not be pre-empted by any interrupt or any interrupt with higher priority, you can use the API Cy_SysLib_EnterCriticalSection() to disable all the interrupts till you complete the code execution. Once the code execution completes, you can call the API Cy_SysLib_ExitCriticalSection() to come back to initial configuration of interrupts.

>>" It really messes with my application. Could I make my own version of this routine that wouldn't block interrupts for so long? (I don't really understand exactly how this routine works.)"

--> We generally do not recommend you to modify the Cy_SysLib_EnterCriticalSection() function or any library functions.

-->You can write your own function where you can disable only those interrupts whichever are required.

If possible, please explain more about your application so that we may suggest you or ideas of implementation.

Thanks

Ganesh

View solution in original post

0 Likes
3 Replies
VenkataD_41
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hi,

When you are executing some important block of code which should not be pre-empted by any interrupt or any interrupt with higher priority, you can use the API Cy_SysLib_EnterCriticalSection() to disable all the interrupts till you complete the code execution. Once the code execution completes, you can call the API Cy_SysLib_ExitCriticalSection() to come back to initial configuration of interrupts.

>>" It really messes with my application. Could I make my own version of this routine that wouldn't block interrupts for so long? (I don't really understand exactly how this routine works.)"

--> We generally do not recommend you to modify the Cy_SysLib_EnterCriticalSection() function or any library functions.

-->You can write your own function where you can disable only those interrupts whichever are required.

If possible, please explain more about your application so that we may suggest you or ideas of implementation.

Thanks

Ganesh

0 Likes
lock attach
Attachments are accessible only for community members.

Hi Ganesh-

Please see this thread for some context: Psoc 6 RTC unixtime.

If I run this snippet:

    for(;;)

    {

        /* Place your application code here. */

        /* Variable used to store date and time information */

        cy_stc_rtc_config_t dateTime;

    

        Cy_GPIO_Write(Pin13_7_PORT, Pin13_7_NUM, 0) ;  

    

        /*Get the current RTC time and date */

        Cy_RTC_GetDateAndTime(&dateTime);    

        Cy_GPIO_Write(Pin13_7_PORT, Pin13_7_NUM, 1) ;          

    

        CyDelay(1);

    }

and look at Pin13_7 with a logic analyzer, I see this:

pastedImage_1.png

So, each call to Cy_RTC_GetDateAndTime is taking around 185 us. Apparently, the interrupts are disabled for most of that time. Coincidentally:

/** Definition of six WCO clocks in microseconds */

#define CY_RTC_DELAY_WHILE_READING_US                (183U)

Does Cy_RTC_SyncFromRtc really need to have interrupts disabled while it is just sleeping?

        /* Delay to guarantee RTC data reading */

        Cy_SysLib_DelayUs(CY_RTC_DELAY_WHILE_READING_US);

0 Likes

I took a look in PSoC 6 MCU with BLE: CY8C63x6, CY8C63x7 Architecture TRM, Document No. 002-18176 Rev. *H, and this is all that it has to say about "Reading RTC User Registers":

To start a read transaction, the firmware should set the

READ bit in the BACKUP_RTC_RW register. When this bit

is set, the RTC registers will be copied to user registers and

frozen so that a coherent RTC value can safely be read by

the firmware. The read transaction is completed by clearing

the READ bit.

The READ bit cannot be set if:

■ RTC is still busy with a previous operation (that is, the

RTC_BUSY bit in the BACKUP_STATUS register is set)

■ WRITE bit in the BACKUP_RTC_RW register is set

The firmware should verify that the above bits are not set

before setting the READ bit.

I don't see anything about a "Delay to guarantee RTC data reading."

So, I tried replacing Cy_RTC_SyncFromRtc  from cy_rtc.h with this:

static void readRTCUserRegisters(void)

{   

    while ((CY_RTC_BUSY == Cy_RTC_GetSyncStatus()) || (_FLD2BOOL(BACKUP_RTC_RW_WRITE, BACKUP_RTC_RW)))

        ; // Spin

    /* Setting RTC Read bit */

    BACKUP_RTC_RW = BACKUP_RTC_RW_READ_Msk;

    /* Clearing RTC Read bit */

    BACKUP_RTC_RW = 0U;

}

and it seems to work fine, even when called very frequently. Is there anything I should watch out for?

0 Likes