|
37 | 37 | #error This port can only be used when the project options are configured to enable hardware floating point support.
|
38 | 38 | #endif
|
39 | 39 |
|
40 |
| -#ifndef configSYSTICK_CLOCK_HZ |
41 |
| - #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ |
42 |
| - /* Ensure the SysTick is clocked at the same frequency as the core. */ |
43 |
| - #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) |
44 |
| -#else |
45 |
| - /* The way the SysTick is clocked is not modified in case it is not the same |
46 |
| - as the core. */ |
47 |
| - #define portNVIC_SYSTICK_CLK_BIT ( 0 ) |
48 |
| -#endif |
49 |
| - |
50 | 40 | /* Constants required to manipulate the core. Registers first... */
|
51 | 41 | #define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
|
52 | 42 | #define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
|
53 | 43 | #define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) )
|
54 | 44 | #define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) )
|
55 | 45 | #define portNVIC_ICSR_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
|
56 | 46 | /* ...then bits in the registers. */
|
| 47 | +#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) |
57 | 48 | #define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
|
58 | 49 | #define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
|
59 | 50 | #define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
|
@@ -103,6 +94,19 @@ occurred while the SysTick counter is stopped during tickless idle
|
103 | 94 | calculations. */
|
104 | 95 | #define portMISSED_COUNTS_FACTOR ( 45UL )
|
105 | 96 |
|
| 97 | +/* Let the user override the default SysTick clock rate. If defined by the |
| 98 | +user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the |
| 99 | +configuration register. */ |
| 100 | +#ifndef configSYSTICK_CLOCK_HZ |
| 101 | + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ |
| 102 | + /* Ensure the SysTick is clocked at the same frequency as the core. */ |
| 103 | + #define portNVIC_SYSTICK_CLK_BIT_SETTING ( portNVIC_SYSTICK_CLK_BIT ) |
| 104 | +#else |
| 105 | + /* Select the option to clock SysTick not at the same frequency as the core. |
| 106 | + The clock used is often a divided version of the core clock. */ |
| 107 | + #define portNVIC_SYSTICK_CLK_BIT_SETTING ( 0 ) |
| 108 | +#endif |
| 109 | + |
106 | 110 | /* Let the user override the pre-loading of the initial LR with the address of
|
107 | 111 | prvTaskExitError() in case it messes up unwinding of the stack in the
|
108 | 112 | debugger. */
|
@@ -615,7 +619,7 @@ void xPortSysTickHandler( void )
|
615 | 619 | be, but using the tickless mode will inevitably result in some tiny
|
616 | 620 | drift of the time maintained by the kernel with respect to calendar
|
617 | 621 | time*/
|
618 |
| - portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT ); |
| 622 | + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_SETTING | portNVIC_SYSTICK_INT_BIT ); |
619 | 623 |
|
620 | 624 | /* Determine if the SysTick clock has already counted to zero and
|
621 | 625 | been set back to the current reload value (the reload back being
|
@@ -665,13 +669,24 @@ void xPortSysTickHandler( void )
|
665 | 669 | portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
|
666 | 670 | }
|
667 | 671 |
|
668 |
| - /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG |
669 |
| - again, then set portNVIC_SYSTICK_LOAD_REG back to its standard |
670 |
| - value. */ |
| 672 | + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again, |
| 673 | + then set portNVIC_SYSTICK_LOAD_REG back to its standard value. If |
| 674 | + the SysTick is not using the core clock, temporarily configure it to |
| 675 | + use the core clock. This configuration forces the SysTick to load |
| 676 | + from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next |
| 677 | + cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready |
| 678 | + to receive the standard value immediately. */ |
671 | 679 | portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
672 |
| - portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; |
673 |
| - vTaskStepTick( ulCompleteTickPeriods ); |
| 680 | + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; |
| 681 | + #if( portNVIC_SYSTICK_CLK_BIT_SETTING != portNVIC_SYSTICK_CLK_BIT ) |
| 682 | + { |
| 683 | + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_SETTING | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT; |
| 684 | + } |
| 685 | + #endif /* portNVIC_SYSTICK_CLK_BIT_SETTING */ |
674 | 686 | portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
| 687 | + |
| 688 | + /* Step the tick to account for any tick periods that elapsed. */ |
| 689 | + vTaskStepTick( ulCompleteTickPeriods ); |
675 | 690 |
|
676 | 691 | /* Exit with interrupts enabled. */
|
677 | 692 | __asm volatile( "cpsie i" ::: "memory" );
|
@@ -702,7 +717,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
702 | 717 |
|
703 | 718 | /* Configure SysTick to interrupt at the requested rate. */
|
704 | 719 | portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
705 |
| - portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); |
| 720 | + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_SETTING | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); |
706 | 721 | }
|
707 | 722 | /*-----------------------------------------------------------*/
|
708 | 723 |
|
|
0 commit comments