]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/portable/IAR/ARM_CM3/port.c
Update PIC32 demo application to remove reliance on PLIB functions.
[freertos] / FreeRTOS / Source / portable / IAR / ARM_CM3 / port.c
index c501e72594bbe98c44b8a28ad99bbf4838164d46..7f8b1bc58061e9f323f7998890660f7b00d75ec6 100644 (file)
@@ -265,6 +265,7 @@ void xPortSysTickHandler( void )
        __weak void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )\r
        {\r
        unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickIncrements;\r
+       portTickType xModifiableIdleTime;\r
 \r
                /* Make sure the SysTick reload value does not overflow the counter. */\r
                if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )\r
@@ -288,19 +289,28 @@ void xPortSysTickHandler( void )
                kernel with respect to calendar time. */\r
                portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;\r
 \r
-               /* If a context switch is pending then abandon the low power entry as\r
-               the context switch might have been pended by an external interrupt that\r
-               requires processing. */\r
-               if( ( portNVIC_INT_CTRL_REG & portNVIC_PENDSVSET_BIT ) != 0 )\r
+               /* Adjust the reload value to take into account that the current\r
+               time slice is already partially complete. */\r
+               ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) );\r
+\r
+               /* Enter a critical section but don't use the taskENTER_CRITICAL()\r
+               method as that will mask interrupts that should exit sleep mode. */\r
+               __disable_interrupt();\r
+\r
+               /* If a context switch is pending or a task is waiting for the scheduler\r
+               to be unsuspended then abandon the low power entry. */\r
+               if( eTaskConfirmSleepModeStatus() == eAbortSleep )\r
                {\r
                        /* Restart SysTick. */\r
                        portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;\r
+\r
+                       /* Re-enable interrupts - see comments above __disable_interrupt()\r
+                       call above. */\r
+                       __enable_interrupt();\r
                }\r
                else\r
                {\r
-                       /* Adjust the reload value to take into account that the current\r
-                       time slice is already partially complete. */\r
-                       ulReloadValue += ( portNVIC_SYSTICK_LOAD_REG - ( portNVIC_SYSTICK_LOAD_REG - portNVIC_SYSTICK_CURRENT_VALUE_REG ) );\r
+                       /* Set the new reload value. */\r
                        portNVIC_SYSTICK_LOAD_REG = ulReloadValue;\r
 \r
                        /* Clear the SysTick count flag and set the count value back to\r
@@ -310,9 +320,14 @@ void xPortSysTickHandler( void )
                        /* Restart SysTick. */\r
                        portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;\r
 \r
-                       /* Sleep until something happens. */\r
-                       configPRE_SLEEP_PROCESSING( xExpectedIdleTime );\r
-                       if( xExpectedIdleTime > 0 )\r
+                       /* Sleep until something happens.  configPRE_SLEEP_PROCESSING() can\r
+                       set its parameter to 0 to indicate that its implementation contains\r
+                       its own wait for interrupt or wait for event instruction, and so wfi\r
+                       should not be executed again.  However, the original expected idle\r
+                       time variable must remain unmodified, so a copy is taken. */\r
+                       xModifiableIdleTime = xExpectedIdleTime;\r
+                       configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
+                       if( xModifiableIdleTime > 0 )\r
                        {\r
                                __WFI();\r
                        }\r
@@ -324,6 +339,10 @@ void xPortSysTickHandler( void )
                        kernel with respect to calendar time. */\r
                        portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;\r
 \r
+                       /* Re-enable interrupts - see comments above __disable_interrupt()\r
+                       call above. */\r
+                       __enable_interrupt();\r
+\r
                        if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )\r
                        {\r
                                /* The tick interrupt has already executed, and the SysTick\r
@@ -373,7 +392,7 @@ void xPortSysTickHandler( void )
  */\r
 __weak void vPortSetupTimerInterrupt( void )\r
 {\r
-       /* Calculate the constants required to configure the tick interrupt. */         \r
+       /* Calculate the constants required to configure the tick interrupt. */\r
        #if configUSE_TICKLESS_IDLE == 1\r
        {\r
                ulTimerReloadValueForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r