PSOC 6: I2C ISR Tickless freeRTOS

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

cross mob
lock attach
Attachments are accessible only for community members.
mvpablo
Level 2
Level 2
10 sign-ins 5 replies posted 5 questions asked

I have an Arduino uno as a master, sending data via I2C to a PSoC 6 slave board CY8CKIT-062S2-43012.

I'm using modustoolbox with freeRTOS. See attached code.

Everything works fine while in DEBUGGING MODE. Basically every time the uno sends data to the  PSoC 6. the data buffer is put as a message in a queue and then another task will take those messages and process them .

But when I flash and run the program again. It just doesn't work. 

I read from some posts that it is because in debug mode the deep sleep is disabled. So I added a callback for deep sleep but still doesn't work. 

then I changed the parameter configUSE_TICKLESS_IDLE in the freeRTOS config file to 0 and that solved the problem. 

What does it mean to have the tickless parameter to zero (0) ? it means that now my app doesn't have power save mode?

Is this the right way to do it? or maybe use HAL to just modify the I2C interrupt to wake up from deepsleep, which I tried but it didn't work?

thanks 

IMG_7721 copy.jpg

 

/* Check if the ModusToolbox Device Configurator Power personality parameter
 * "System Idle Power Mode" is set to either "CPU Sleep" or "System Deep Sleep".
 */
#if defined(CY_CFG_PWR_SYS_IDLE_MODE) && \
    ((CY_CFG_PWR_SYS_IDLE_MODE == CY_CFG_PWR_MODE_SLEEP) || \
     (CY_CFG_PWR_SYS_IDLE_MODE == CY_CFG_PWR_MODE_DEEPSLEEP))
/* Enable low power tickless functionality. The RTOS abstraction library
 * provides the compatible implementation of the vApplicationSleep hook:
 * https://github.com/cypresssemiconductorco/abstraction-rtos#freertos
 * The Low Power Assistant library provides additional portable configuration layer
 * for low-power features supported by the PSoC 6 devices:
 * https://github.com/cypresssemiconductorco/lpa
 */
extern void vApplicationSleep( uint32_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime )
//#define configUSE_TICKLESS_IDLE                 2
#define configUSE_TICKLESS_IDLE                 0
#else
#define configUSE_TICKLESS_IDLE                 0
#endif


/* Deep Sleep Latency Configuration */
#if( CY_CFG_PWR_DEEPSLEEP_LATENCY > 0 )
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP   CY_CFG_PWR_DEEPSLEEP_LATENCY
#endif
0 Likes
1 Solution
Krupashankar
Moderator
Moderator
Moderator
500 replies posted 50 likes received 25 likes received

Hi @mvpablo ,

Ques 1 : I read from some posts that it is because in debug mode the deep sleep is disabled. So I added a callback for deep sleep but still doesn't work.

In debug mode, deep sleep will always be disabled and even defining call back function doesn’t enable deep sleep. The device needs to be programmed to verify the functionality of deep sleep mode.

Ques 2 : What does it mean to have the tickless parameter to zero (0) ? it means that now my app doesn't have power save mode?

Set configUSE_TICKLESS_IDLE to 1 to use the low power tickless mode, or 0 to disable deep sleep mode. Built in tickless idle functionality is enabled by defining configUSE_TICKLESS_IDLE as 1 in FreeRTOSConfig.h (for ports that support this feature). User defined tickless idle functionality can be provided for any FreeRTOS port (including those that include a built in implementation) by defining configUSE_TICKLESS_IDLE to 2 in FreeRTOSConfig.h.

Ques 3 : Is this the right way to do it? or maybe use HAL to just modify the I2C interrupt to wake up from deep sleep, which I tried but it didn't work?

You can have I2C communication in deep sleep mode by enabling the following registers

In deep sleep power mode when EC_AM = '1' and EC_OP = '0' clk_scb is not available, so the
clock will be streched on an incoming address until clk_scb is available. After clk_scb is available the address ACK will follow S_READY_ADDR_ACK

Krupashankar_0-1631014373145.png

 

Please refer to technical reference manual in section 26.5.6 I2C Buffer Modes https://www.cypress.com/file/399201/download

 

Thanks,

Krupashankar

View solution in original post

0 Likes
1 Reply
Krupashankar
Moderator
Moderator
Moderator
500 replies posted 50 likes received 25 likes received

Hi @mvpablo ,

Ques 1 : I read from some posts that it is because in debug mode the deep sleep is disabled. So I added a callback for deep sleep but still doesn't work.

In debug mode, deep sleep will always be disabled and even defining call back function doesn’t enable deep sleep. The device needs to be programmed to verify the functionality of deep sleep mode.

Ques 2 : What does it mean to have the tickless parameter to zero (0) ? it means that now my app doesn't have power save mode?

Set configUSE_TICKLESS_IDLE to 1 to use the low power tickless mode, or 0 to disable deep sleep mode. Built in tickless idle functionality is enabled by defining configUSE_TICKLESS_IDLE as 1 in FreeRTOSConfig.h (for ports that support this feature). User defined tickless idle functionality can be provided for any FreeRTOS port (including those that include a built in implementation) by defining configUSE_TICKLESS_IDLE to 2 in FreeRTOSConfig.h.

Ques 3 : Is this the right way to do it? or maybe use HAL to just modify the I2C interrupt to wake up from deep sleep, which I tried but it didn't work?

You can have I2C communication in deep sleep mode by enabling the following registers

In deep sleep power mode when EC_AM = '1' and EC_OP = '0' clk_scb is not available, so the
clock will be streched on an incoming address until clk_scb is available. After clk_scb is available the address ACK will follow S_READY_ADDR_ACK

Krupashankar_0-1631014373145.png

 

Please refer to technical reference manual in section 26.5.6 I2C Buffer Modes https://www.cypress.com/file/399201/download

 

Thanks,

Krupashankar

0 Likes