From 2c0927126fe1e07b990f8609ff84e58384328a9d Mon Sep 17 00:00:00 2001 From: Cristian Pop Date: Wed, 28 Jul 2021 09:45:43 +0300 Subject: [PATCH 1/5] Update AVR port files --- portable/GCC/AVR_AVRDx/port.c | 277 +++++++----- portable/GCC/AVR_AVRDx/port.c.bak | 506 ++++++++++++++++++++++ portable/GCC/AVR_AVRDx/porthardware.h | 110 ++++- portable/GCC/AVR_AVRDx/porthardware.h.bak | 137 ++++++ portable/GCC/AVR_AVRDx/portmacro.h | 156 +++++++ portable/GCC/AVR_AVRDx/portmacro.h.bak | 112 +++++ 6 files changed, 1170 insertions(+), 128 deletions(-) create mode 100644 portable/GCC/AVR_AVRDx/port.c.bak create mode 100644 portable/GCC/AVR_AVRDx/porthardware.h.bak create mode 100644 portable/GCC/AVR_AVRDx/portmacro.h.bak diff --git a/portable/GCC/AVR_AVRDx/port.c b/portable/GCC/AVR_AVRDx/port.c index f81af945b7..fd3e29303d 100644 --- a/portable/GCC/AVR_AVRDx/port.c +++ b/portable/GCC/AVR_AVRDx/port.c @@ -49,119 +49,6 @@ extern volatile RTOS_TCB_t * volatile pxCurrentTCB; /*-----------------------------------------------------------*/ -/* - * Macro to save all the general purpose registers, the save the stack pointer - * into the TCB. - * - * The first thing we do is save the flags then disable interrupts. This is to - * guard our stack against having a context switch interrupt after we have already - * pushed the registers onto the stack - causing the 32 registers to be on the - * stack twice. - * - * r1 is set to zero as the compiler expects it to be thus, however some - * of the math routines make use of R1. - * - * The interrupts will have been disabled during the call to portSAVE_CONTEXT() - * so we need not worry about reading/writing to the stack pointer. - */ - -#define portSAVE_CONTEXT() \ - asm volatile ( "push r0 \n\t" \ - "in r0, __SREG__ \n\t" \ - "cli \n\t" \ - "push r0 \n\t" \ - "in r0, __RAMPZ__ \n\t" \ - "push r0 \n\t" \ - "push r1 \n\t" \ - "clr r1 \n\t" \ - "push r2 \n\t" \ - "push r3 \n\t" \ - "push r4 \n\t" \ - "push r5 \n\t" \ - "push r6 \n\t" \ - "push r7 \n\t" \ - "push r8 \n\t" \ - "push r9 \n\t" \ - "push r10 \n\t" \ - "push r11 \n\t" \ - "push r12 \n\t" \ - "push r13 \n\t" \ - "push r14 \n\t" \ - "push r15 \n\t" \ - "push r16 \n\t" \ - "push r17 \n\t" \ - "push r18 \n\t" \ - "push r19 \n\t" \ - "push r20 \n\t" \ - "push r21 \n\t" \ - "push r22 \n\t" \ - "push r23 \n\t" \ - "push r24 \n\t" \ - "push r25 \n\t" \ - "push r26 \n\t" \ - "push r27 \n\t" \ - "push r28 \n\t" \ - "push r29 \n\t" \ - "push r30 \n\t" \ - "push r31 \n\t" \ - "lds r26, pxCurrentTCB \n\t" \ - "lds r27, pxCurrentTCB + 1 \n\t" \ - "in r0, __SP_L__ \n\t" \ - "st x+, r0 \n\t" \ - "in r0, __SP_H__ \n\t" \ - "st x+, r0 \n\t" ); - -/* - * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during - * the context save so we can write to the stack pointer. - */ - -#define portRESTORE_CONTEXT() \ - asm volatile ( "lds r26, pxCurrentTCB \n\t" \ - "lds r27, pxCurrentTCB + 1 \n\t" \ - "ld r28, x+ \n\t" \ - "out __SP_L__, r28 \n\t" \ - "ld r29, x+ \n\t" \ - "out __SP_H__, r29 \n\t" \ - "pop r31 \n\t" \ - "pop r30 \n\t" \ - "pop r29 \n\t" \ - "pop r28 \n\t" \ - "pop r27 \n\t" \ - "pop r26 \n\t" \ - "pop r25 \n\t" \ - "pop r24 \n\t" \ - "pop r23 \n\t" \ - "pop r22 \n\t" \ - "pop r21 \n\t" \ - "pop r20 \n\t" \ - "pop r19 \n\t" \ - "pop r18 \n\t" \ - "pop r17 \n\t" \ - "pop r16 \n\t" \ - "pop r15 \n\t" \ - "pop r14 \n\t" \ - "pop r13 \n\t" \ - "pop r12 \n\t" \ - "pop r11 \n\t" \ - "pop r10 \n\t" \ - "pop r9 \n\t" \ - "pop r8 \n\t" \ - "pop r7 \n\t" \ - "pop r6 \n\t" \ - "pop r5 \n\t" \ - "pop r4 \n\t" \ - "pop r3 \n\t" \ - "pop r2 \n\t" \ - "pop r1 \n\t" \ - "pop r0 \n\t" \ - "out __RAMPZ__, r0 \n\t" \ - "pop r0 \n\t" \ - "out __SREG__, r0 \n\t" \ - "pop r0 \n\t" ); - -/*-----------------------------------------------------------*/ - /* * Perform hardware setup to enable ticks from timer. */ @@ -206,8 +93,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, pxTopOfStack--; *pxTopOfStack = portFLAGS_INT_ENABLED; pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x00; /* RAMPZ */ +#if defined(__AVR_HAVE_RAMPZ__) + *pxTopOfStack = (StackType_t)0x00; /* RAMPZ */ pxTopOfStack--; +#endif /* Now the remaining registers. The compiler expects R1 to be 0. */ *pxTopOfStack = ( StackType_t ) 0x00; /* R1 */ @@ -310,11 +199,15 @@ void vPortYieldFromTick( void ) */ static void prvSetupTimerInterrupt( void ) { + /* Configure low-power timer used in tickless mode */ +#if (configUSE_TICKLESS_IDLE == 1) + RTC_INIT(); +#endif TICK_init(); } /*-----------------------------------------------------------*/ -#if configUSE_PREEMPTION == 1 +#if (configUSE_PREEMPTION == 1) /* * Tick ISR for preemptive scheduler. We can use a naked attribute as @@ -344,3 +237,157 @@ static void prvSetupTimerInterrupt( void ) xTaskIncrementTick(); } #endif /* if configUSE_PREEMPTION == 1 */ + +#if (configUSE_TICKLESS_IDLE == 1) + +volatile uint32_t RTC_OVF_Count = 0; + +ISR(RTC_CNT_vect) +{ + if (RTC.INTFLAGS & RTC_OVF_bm ) + { + RTC_OVF_Count += 0x00010000; + RTC.INTFLAGS = (RTC_OVF_bm); + } + + if (RTC.INTFLAGS & RTC_CMP_bm ) + { + RTC.INTFLAGS = (RTC_CMP_bm); + //Disable compare interrupt + RTC.INTCTRL &= (0xFF ^ RTC_CMP_bm); + } + +} + +static uint32_t ulGetExternalTime(void) +{ + uint32_t time_rtc; + + while (RTC.STATUS & RTC_CNTBUSY_bm) + { + ; + } + time_rtc = RTC.CNT; + time_rtc += RTC_OVF_Count; + return time_rtc; +} + +static void vSetWakeTimeInterrupt(uint16_t xExpectedIdleTime) +{ + uint32_t rtc_cnt_time; + + /* compute the required */ + rtc_cnt_time = RTC_TICKS_TO_COUNTS(xExpectedIdleTime); + rtc_cnt_time += ulGetExternalTime(); + + while (RTC.STATUS & RTC_CMPBUSY_bm) + { + ; + } + RTC.CMP = (rtc_cnt_time & 0xFFFF); + + //Enable compare interrupt + RTC.INTCTRL |= RTC_CMP_bm; +} + +/* Define the function that is called by portSUPPRESS_TICKS_AND_SLEEP(). */ +__attribute__((weak)) void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) +{ + eSleepModeStatus eSleepStatus; + uint32_t ulLowPowerTimeBeforeSleep, ulLowPowerTimeAfterSleep; + + /* Read the current time from a time source that will remain operational + while the microcontroller is in a low power state. */ + ulLowPowerTimeBeforeSleep = ulGetExternalTime(); + + /* Stop the timer that is generating the tick interrupt. */ + TICK_TMR_STOP(); + + /* Enter a critical section that will not effect interrupts bringing the MCU + out of sleep mode. */ + portDISABLE_INTERRUPTS(); + + /* Ensure it is still ok to enter the sleep mode. */ + eSleepStatus = eTaskConfirmSleepModeStatus(); + + if (eSleepStatus == eAbortSleep) + { + /* A task has been moved out of the Blocked state since this macro was + * executed, or a context switch is being held pending. Do not enter a + * sleep state. Restart the tick and exit the critical section. */ + TICK_TMR_START(); + portENABLE_INTERRUPTS(); + } + else + { + if (eSleepStatus == eNoTasksWaitingTimeout) + { + /* A user definable macro that allows application code to be inserted + * here. Such application code can be used to minimize power consumption + * further by turning off IO, peripheral clocks, the Flash, etc. */ + configPRE_PWR_DOWN_PROCESSING(); + + /* There are no running state tasks and no tasks that are blocked with a + * time out. Assuming the application does not care if the tick time slips + * with respect to calendar time then enter a deep sleep that can only be + * woken by (in this demo case) the user button being pushed on the + * Curiosity Nano board. If the application does require the tick time + * to keep better track of the calender time then the PIT peripheral can be + * used to make rough adjustments. */ + portSET_MODE_AND_SLEEP(SLEEP_MODE_PWR_DOWN); + + /* A user definable macro that allows application code to be inserted + * here. Such application code can be used to reverse any actions taken + * by the configPRE_STOP_PROCESSING() */ + configPOST_PWR_DOWN_PROCESSING(); + } + else + { + /* Configure an interrupt to bring the microcontroller out of its low + * power state at the time the kernel next needs to execute. The + * interrupt must be generated from a source that remains operational + * when the microcontroller is in a low power state. */ + vSetWakeTimeInterrupt(xExpectedIdleTime); + + /* Allow the application to define some pre-sleep processing. This is + * the standard configPRE_SLEEP_PROCESSING() macro as described on the + * FreeRTOS.org website. */ + configPRE_SLEEP_PROCESSING(xExpectedIdleTime); + + /* Enter the low power state. */ + portSET_MODE_AND_SLEEP(SLEEP_MODE_STANDBY); + + /* Determine how long the microcontroller was actually in a low power + * state for, which will be less than xExpectedIdleTime if the + * microcontroller was brought out of low power mode by an interrupt + * other than that configured by the vSetWakeTimeInterrupt() call. + * Note that the scheduler is suspended before + * portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when + * portSUPPRESS_TICKS_AND_SLEEP() returns. Therefore no other tasks will + * execute until this function completes. */ + ulLowPowerTimeAfterSleep = ulGetExternalTime(); + + /* Allow the application to define some post sleep processing. This is + * the standard configPOST_SLEEP_PROCESSING() macro, as described on the + * FreeRTOS.org website. + * It can be used to reverse the actions of configPRE_SLEEP_PROCESSING(), + * and in so doing, return the microcontroller back to its fully operational state */ + configPOST_SLEEP_PROCESSING(xExpectedIdleTime); + + /* Correct the kernels tick count to account for the time the + * microcontroller spent in its low power state. */ + vTaskStepTick(RTC_COUNTS_TO_TICKS(ulLowPowerTimeAfterSleep - ulLowPowerTimeBeforeSleep)); + // vTaskStepTick(xExpectedIdleTime); + + } + + /* Exit the critical section - it might be possible to do this immediately + * after the SET_MODE_AND_SLEEP calls. */ + portENABLE_INTERRUPTS(); + + /* Restart the timer that is generating the tick interrupt. */ + TICK_TMR_START(); + } +} + +#endif diff --git a/portable/GCC/AVR_AVRDx/port.c.bak b/portable/GCC/AVR_AVRDx/port.c.bak new file mode 100644 index 0000000000..1656fd536c --- /dev/null +++ b/portable/GCC/AVR_AVRDx/port.c.bak @@ -0,0 +1,506 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#include + +#include +#include "porthardware.h" +#include "FreeRTOS.h" +#include "task.h" + +/*----------------------------------------------------------- +* Implementation of functions defined in portable.h for the AVR port. +*----------------------------------------------------------*/ + +/* Start tasks with interrupts enables. */ +#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 ) + +/*-----------------------------------------------------------*/ + +/* We require the address of the pxCurrentTCB variable, but don't want to know + * any details of its type. */ +typedef void RTOS_TCB_t; +extern volatile RTOS_TCB_t * volatile pxCurrentTCB; + +/*-----------------------------------------------------------*/ + +/* + * Macro to save all the general purpose registers, the save the stack pointer + * into the TCB. + * + * The first thing we do is save the flags then disable interrupts. This is to + * guard our stack against having a context switch interrupt after we have already + * pushed the registers onto the stack - causing the 32 registers to be on the + * stack twice. + * + * r1 is set to zero as the compiler expects it to be thus, however some + * of the math routines make use of R1. + * + * The interrupts will have been disabled during the call to portSAVE_CONTEXT() + * so we need not worry about reading/writing to the stack pointer. + */ + +#define portSAVE_CONTEXT() \ + asm volatile ( "push r0 \n\t" \ + "in r0, __SREG__ \n\t" \ + "cli \n\t" \ + "push r0 \n\t" \ + "in r0, __RAMPZ__ \n\t" \ + "push r0 \n\t" \ + "push r1 \n\t" \ + "clr r1 \n\t" \ + "push r2 \n\t" \ + "push r3 \n\t" \ + "push r4 \n\t" \ + "push r5 \n\t" \ + "push r6 \n\t" \ + "push r7 \n\t" \ + "push r8 \n\t" \ + "push r9 \n\t" \ + "push r10 \n\t" \ + "push r11 \n\t" \ + "push r12 \n\t" \ + "push r13 \n\t" \ + "push r14 \n\t" \ + "push r15 \n\t" \ + "push r16 \n\t" \ + "push r17 \n\t" \ + "push r18 \n\t" \ + "push r19 \n\t" \ + "push r20 \n\t" \ + "push r21 \n\t" \ + "push r22 \n\t" \ + "push r23 \n\t" \ + "push r24 \n\t" \ + "push r25 \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "push r28 \n\t" \ + "push r29 \n\t" \ + "push r30 \n\t" \ + "push r31 \n\t" \ + "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "in r0, __SP_L__ \n\t" \ + "st x+, r0 \n\t" \ + "in r0, __SP_H__ \n\t" \ + "st x+, r0 \n\t" ); + +/* + * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during + * the context save so we can write to the stack pointer. + */ + +#define portRESTORE_CONTEXT() \ + asm volatile ( "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "ld r28, x+ \n\t" \ + "out __SP_L__, r28 \n\t" \ + "ld r29, x+ \n\t" \ + "out __SP_H__, r29 \n\t" \ + "pop r31 \n\t" \ + "pop r30 \n\t" \ + "pop r29 \n\t" \ + "pop r28 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" \ + "pop r25 \n\t" \ + "pop r24 \n\t" \ + "pop r23 \n\t" \ + "pop r22 \n\t" \ + "pop r21 \n\t" \ + "pop r20 \n\t" \ + "pop r19 \n\t" \ + "pop r18 \n\t" \ + "pop r17 \n\t" \ + "pop r16 \n\t" \ + "pop r15 \n\t" \ + "pop r14 \n\t" \ + "pop r13 \n\t" \ + "pop r12 \n\t" \ + "pop r11 \n\t" \ + "pop r10 \n\t" \ + "pop r9 \n\t" \ + "pop r8 \n\t" \ + "pop r7 \n\t" \ + "pop r6 \n\t" \ + "pop r5 \n\t" \ + "pop r4 \n\t" \ + "pop r3 \n\t" \ + "pop r2 \n\t" \ + "pop r1 \n\t" \ + "pop r0 \n\t" \ + "out __RAMPZ__, r0 \n\t" \ + "pop r0 \n\t" \ + "out __SREG__, r0 \n\t" \ + "pop r0 \n\t" ); + +/*-----------------------------------------------------------*/ + +/* + * Perform hardware setup to enable ticks from timer. + */ +static void prvSetupTimerInterrupt( void ); +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, + TaskFunction_t pxCode, + void * pvParameters ) +{ + uint16_t usAddress; + + /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ + + /* Place a few bytes of known values on the bottom of the stack. + * This is just useful for debugging. Uncomment if needed. */ + /* *pxTopOfStack = 0x11; */ + /* pxTopOfStack--; */ + /* *pxTopOfStack = 0x22; */ + /* pxTopOfStack--; */ + /* *pxTopOfStack = 0x33; */ + /* pxTopOfStack--; */ + + /* The start of the task code will be popped off the stack last, so place + * it on first. */ + usAddress = ( uint16_t ) pxCode; + *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff ); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff ); + pxTopOfStack--; + + /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). + * portSAVE_CONTEXT places the flags on the stack immediately after r0 + * to ensure the interrupts get disabled as soon as possible, and so ensuring + * the stack use is minimal should a context switch interrupt occur. */ + *pxTopOfStack = ( StackType_t ) 0x00; /* R0 */ + pxTopOfStack--; + *pxTopOfStack = portFLAGS_INT_ENABLED; + pxTopOfStack--; +#if defined(__AVR_HAVE_RAMPZ__) + *pxTopOfStack = (StackType_t)0x00; /* RAMPZ */ + pxTopOfStack--; +#endif + + /* Now the remaining registers. The compiler expects R1 to be 0. */ + *pxTopOfStack = ( StackType_t ) 0x00; /* R1 */ + + /* Leave R2 - R23 untouched */ + pxTopOfStack -= 23; + + /* Place the parameter on the stack in the expected location. */ + usAddress = ( uint16_t ) pvParameters; + *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff ); + pxTopOfStack--; + + usAddress >>= 8; + *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff ); + + /* Leave register R26 - R31 untouched */ + pxTopOfStack -= 7; + + /*lint +e950 +e611 +e923 */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +BaseType_t xPortStartScheduler( void ) +{ + /* Setup the hardware to generate the tick. */ + prvSetupTimerInterrupt(); + + /* Restore the context of the first task that is going to run. */ + portRESTORE_CONTEXT(); + + /* Simulate a function call end as generated by the compiler. We will now + * jump to the start of the task the context of which we have just restored. */ + asm volatile ( "ret" ); + + /* Should not get here. */ + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* vPortEndScheduler is not implemented in this port. */ +} +/*-----------------------------------------------------------*/ + +/* + * Manual context switch. The first thing we do is save the registers so we + * can use a naked attribute. + */ +void vPortYield( void ) __attribute__( ( naked ) ); +void vPortYield( void ) +{ + portSAVE_CONTEXT(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + asm volatile ( "ret" ); +} +/*-----------------------------------------------------------*/ + +/* + * Manual context switch callable from ISRs. The first thing + * we do is save the registers so we can use a naked attribute. + */ +void vPortYieldFromISR( void ) __attribute__( ( naked ) ); +void vPortYieldFromISR( void ) +{ + portSAVE_CONTEXT(); + vTaskSwitchContext(); + portRESTORE_CONTEXT(); + asm volatile ( "reti" ); +} +/*-----------------------------------------------------------*/ + +/* + * Context switch function used by the tick. This must be identical to + * vPortYield() from the call to vTaskSwitchContext() onwards. The only + * difference from vPortYield() is the tick count is incremented as the + * call comes from the tick ISR. + */ +void vPortYieldFromTick( void ) __attribute__( ( naked ) ); +void vPortYieldFromTick( void ) +{ + portSAVE_CONTEXT(); + + if( xTaskIncrementTick() != pdFALSE ) + { + vTaskSwitchContext(); + } + + portRESTORE_CONTEXT(); + + asm volatile ( "reti" ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup timer to generate a tick interrupt. + */ +static void prvSetupTimerInterrupt( void ) +{ + /* Configure low-power timer used in tickless mode */ +#if (configUSE_TICKLESS_IDLE == 1) + RTC_INIT(); +#endif + TICK_init(); +} +/*-----------------------------------------------------------*/ + +#if (configUSE_PREEMPTION == 1) + +/* + * Tick ISR for preemptive scheduler. We can use a naked attribute as + * the context is saved at the start of vPortYieldFromTick(). The tick + * count is incremented after the context is saved. + */ + ISR( TICK_INT_vect, ISR_NAKED ) + { + /* Clear tick interrupt flag. */ + CLR_INT( INT_FLAGS, INT_MASK ); + + vPortYieldFromTick(); + + asm volatile ( "reti" ); + } +#else /* if configUSE_PREEMPTION == 1 */ + +/* + * Tick ISR for the cooperative scheduler. All this does is increment the + * tick count. We don't need to switch context, this can only be done by + * manual calls to taskYIELD(); + */ + ISR( TICK_INT_vect ) + { + /* Clear tick interrupt flag. */ + INT_FLAGS = INT_MASK; + xTaskIncrementTick(); + } +#endif /* if configUSE_PREEMPTION == 1 */ + +#if (configUSE_TICKLESS_IDLE == 1) + +volatile uint32_t RTC_OVF_Count = 0; + +ISR(RTC_CNT_vect) +{ + if (RTC.INTFLAGS & RTC_OVF_bm ) + { + RTC_OVF_Count += 0x00010000; + RTC.INTFLAGS = (RTC_OVF_bm); + } + + if (RTC.INTFLAGS & RTC_CMP_bm ) + { + RTC.INTFLAGS = (RTC_CMP_bm); + //Disable compare interrupt + RTC.INTCTRL &= (0xFF ^ RTC_CMP_bm); + } + +} + +static uint32_t ulGetExternalTime(void) +{ + uint32_t time_rtc; + + while (RTC.STATUS & RTC_CNTBUSY_bm) + { + ; + } + time_rtc = RTC.CNT; + time_rtc += RTC_OVF_Count; + return time_rtc; +} + +static void vSetWakeTimeInterrupt(uint16_t xExpectedIdleTime) +{ + uint32_t rtc_cnt_time; + + /* compute the required */ + rtc_cnt_time = RTC_TICKS_TO_COUNTS(xExpectedIdleTime); + rtc_cnt_time += ulGetExternalTime(); + + while (RTC.STATUS & RTC_CMPBUSY_bm) + { + ; + } + RTC.CMP = (rtc_cnt_time & 0xFFFF); + + //Enable compare interrupt + RTC.INTCTRL |= RTC_CMP_bm; +} + +/* Define the function that is called by portSUPPRESS_TICKS_AND_SLEEP(). */ +__attribute__((weak)) void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) +{ + eSleepModeStatus eSleepStatus; + uint32_t ulLowPowerTimeBeforeSleep, ulLowPowerTimeAfterSleep; + + /* Read the current time from a time source that will remain operational + while the microcontroller is in a low power state. */ + ulLowPowerTimeBeforeSleep = ulGetExternalTime(); + + /* Stop the timer that is generating the tick interrupt. */ + TICK_TMR_STOP(); + + /* Enter a critical section that will not effect interrupts bringing the MCU + out of sleep mode. */ + portDISABLE_INTERRUPTS(); + + /* Ensure it is still ok to enter the sleep mode. */ + eSleepStatus = eTaskConfirmSleepModeStatus(); + + if (eSleepStatus == eAbortSleep) + { + /* A task has been moved out of the Blocked state since this macro was + * executed, or a context switch is being held pending. Do not enter a + * sleep state. Restart the tick and exit the critical section. */ + TICK_TMR_START(); + portENABLE_INTERRUPTS(); + } + else + { + if (eSleepStatus == eNoTasksWaitingTimeout) + { + /* A user definable macro that allows application code to be inserted + * here. Such application code can be used to minimize power consumption + * further by turning off IO, peripheral clocks, the Flash, etc. */ + configPRE_PWR_DOWN_PROCESSING(); + + /* There are no running state tasks and no tasks that are blocked with a + * time out. Assuming the application does not care if the tick time slips + * with respect to calendar time then enter a deep sleep that can only be + * woken by (in this demo case) the user button being pushed on the + * Curiosity Nano board. If the application does require the tick time + * to keep better track of the calender time then the PIT peripheral can be + * used to make rough adjustments. */ + portSET_MODE_AND_SLEEP(SLEEP_MODE_PWR_DOWN); + + /* A user definable macro that allows application code to be inserted + * here. Such application code can be used to reverse any actions taken + * by the configPRE_STOP_PROCESSING() */ + configPOST_PWR_DOWN_PROCESSING(); + } + else + { + /* Configure an interrupt to bring the microcontroller out of its low + * power state at the time the kernel next needs to execute. The + * interrupt must be generated from a source that remains operational + * when the microcontroller is in a low power state. */ + vSetWakeTimeInterrupt(xExpectedIdleTime); + + /* Allow the application to define some pre-sleep processing. This is + * the standard configPRE_SLEEP_PROCESSING() macro as described on the + * FreeRTOS.org website. */ + configPRE_SLEEP_PROCESSING(xExpectedIdleTime); + + /* Enter the low power state. */ + portSET_MODE_AND_SLEEP(SLEEP_MODE_STANDBY); + + /* Determine how long the microcontroller was actually in a low power + * state for, which will be less than xExpectedIdleTime if the + * microcontroller was brought out of low power mode by an interrupt + * other than that configured by the vSetWakeTimeInterrupt() call. + * Note that the scheduler is suspended before + * portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when + * portSUPPRESS_TICKS_AND_SLEEP() returns. Therefore no other tasks will + * execute until this function completes. */ + ulLowPowerTimeAfterSleep = ulGetExternalTime(); + + /* Allow the application to define some post sleep processing. This is + * the standard configPOST_SLEEP_PROCESSING() macro, as described on the + * FreeRTOS.org website. + * It can be used to reverse the actions of configPRE_SLEEP_PROCESSING(), + * and in so doing, return the microcontroller back to its fully operational state */ + configPOST_SLEEP_PROCESSING(xExpectedIdleTime); + + /* Correct the kernels tick count to account for the time the + * microcontroller spent in its low power state. */ + vTaskStepTick(RTC_COUNTS_TO_TICKS(ulLowPowerTimeAfterSleep - ulLowPowerTimeBeforeSleep)); + // vTaskStepTick(xExpectedIdleTime); + + } + + /* Exit the critical section - it might be possible to do this immediately + * after the SET_MODE_AND_SLEEP calls. */ + portENABLE_INTERRUPTS(); + + /* Restart the timer that is generating the tick interrupt. */ + TICK_TMR_START(); + } +} + +#endif diff --git a/portable/GCC/AVR_AVRDx/porthardware.h b/portable/GCC/AVR_AVRDx/porthardware.h index ca0302e324..52e3f12935 100644 --- a/portable/GCC/AVR_AVRDx/porthardware.h +++ b/portable/GCC/AVR_AVRDx/porthardware.h @@ -55,6 +55,15 @@ TCB0.INTCTRL = TCB_CAPT_bm; \ TCB0.CTRLA = TCB_ENABLE_bm; \ } + + #define TICK_TMR_STOP() TCB0.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB0.INTFLAGS = TCB_CAPT_bm; \ + TCB0.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB0.CNT + #define TICK_INT_READY() (TCB0.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 1 ) @@ -68,6 +77,15 @@ TCB1.INTCTRL = TCB_CAPT_bm; \ TCB1.CTRLA = TCB_ENABLE_bm; \ } + + #define TICK_TMR_STOP() TCB1.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB1.INTFLAGS = TCB_CAPT_bm; \ + TCB1.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB1.CNT + #define TICK_INT_READY() (TCB1.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 2 ) @@ -81,6 +99,15 @@ TCB2.INTCTRL = TCB_CAPT_bm; \ TCB2.CTRLA = TCB_ENABLE_bm; \ } + + #define TICK_TMR_STOP() TCB2.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB2.INTFLAGS = TCB_CAPT_bm; \ + TCB2.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB2.CNT + #define TICK_INT_READY() (TCB2.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 3 ) @@ -94,6 +121,15 @@ TCB3.INTCTRL = TCB_CAPT_bm; \ TCB3.CTRLA = TCB_ENABLE_bm; \ } + + #define TICK_TMR_STOP() TCB3.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB3.INTFLAGS = TCB_CAPT_bm; \ + TCB3.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB3.CNT + #define TICK_INT_READY() (TCB3.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 4 ) @@ -107,31 +143,79 @@ TCB4.INTCTRL = TCB_CAPT_bm; \ TCB4.CTRLA = TCB_ENABLE_bm; \ } + #define TICK_TMR_STOP() TCB4.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB4.INTFLAGS = TCB_CAPT_bm; \ + TCB4.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB4.CNT + #define TICK_INT_READY() (TCB4.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 5 ) - #define TICK_INT_vect RTC_CNT_vect - #define INT_FLAGS RTC_INTFLAGS - #define INT_MASK RTC_OVF_bm - -/* Hertz to period for RTC setup */ - #define RTC_PERIOD_HZ( x ) ( 32768 * ( ( 1.0 / x ) ) ) - #define TICK_init() \ - { \ - while( RTC.STATUS > 0 ) {; } \ - RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \ - RTC.PER = RTC_PERIOD_HZ( configTICK_RATE_HZ ); \ - RTC.INTCTRL |= 1 << RTC_OVF_bp; \ - } + #if ( configUSE_TICKLESS_IDLE == 1 ) + + /* RTC is not supported as tick timer when tickless mode is used */ + #error Invalid timer setting. + + #else + + #define TICK_INT_vect RTC_CNT_vect + #define INT_FLAGS RTC_INTFLAGS + #define INT_MASK RTC_OVF_bm + + /* Hertz to period for RTC setup */ + #define RTC_PERIOD_HZ( x ) ( 32768 * ( ( 1.0 / x ) ) ) + #define TICK_init() \ + { \ + while( RTC.STATUS > 0 ) {; } \ + RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \ + RTC.PER = RTC_PERIOD_HZ( configTICK_RATE_HZ ); \ + RTC.INTCTRL |= 1 << RTC_OVF_bp; \ + } + #undef TICK_TMR_STOP() + #undef TICK_TMR_START() + #undef TICK_TMR_READ() + #undef TICK_INT_READY() + #endif #else /* if ( configUSE_TIMER_INSTANCE == 0 ) */ #undef TICK_INT_vect #undef INT_FLAGS #undef INT_MASK #undef TICK_init() + #undef TICK_TMR_STOP() + #undef TICK_TMR_START() + #undef TICK_TMR_READ() + #undef TICK_INT_READY() #error Invalid timer setting. #endif /* if ( configUSE_TIMER_INSTANCE == 0 ) */ /*-----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + +#define LOW_POWER_CLOCK (32768UL) + +#define RTC_TICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define RTC_TICKS_TO_COUNTS(tick_cnt) (uint32_t)(((float)(tick_cnt * LOW_POWER_CLOCK)/configTICK_RATE_HZ) - 0.5) +#define RTC_COUNTS_TO_TICKS(counts) (uint32_t)((float)((counts * 1.0) * configTICK_RATE_HZ)/LOW_POWER_CLOCK ) + + +#define RTC_INIT() \ +{ \ + while( RTC.STATUS > 0 ) {; } \ + RTC.PER = 0xFFFF; \ + RTC.CMP = 0x3FFF; \ + RTC.CNT = 0; \ + RTC.INTFLAGS = RTC_OVF_bm | RTC_CMP_bm; \ + RTC.CTRLA = RTC_RUNSTDBY_bm | RTC_PRESCALER_DIV1_gc | RTC_RTCEN_bm ; \ + RTC.INTCTRL = RTC_OVF_bm | RTC_CMP_bm; \ +} + +#endif + + #endif /* PORTHARDWARE_H */ diff --git a/portable/GCC/AVR_AVRDx/porthardware.h.bak b/portable/GCC/AVR_AVRDx/porthardware.h.bak new file mode 100644 index 0000000000..ca0302e324 --- /dev/null +++ b/portable/GCC/AVR_AVRDx/porthardware.h.bak @@ -0,0 +1,137 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PORTHARDWARE_H +#define PORTHARDWARE_H + +#include "FreeRTOSConfig.h" + +/*-----------------------------------------------------------*/ + +#define CLR_INT( FLAG_REG, FLAG_MASK ) \ + asm volatile ( \ + "push r16\n\t" \ + "ldi r16, %1\n\t" \ + "sts %0, r16\n\t" \ + "pop r16\n\t" \ + : \ + : "i" ( _SFR_MEM_ADDR( FLAG_REG ) ), "i" ( ( uint8_t ) ( FLAG_MASK ) ) \ + ); + +#if ( configUSE_TIMER_INSTANCE == 0 ) + + #define TICK_INT_vect TCB0_INT_vect + #define INT_FLAGS TCB0_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB0.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB0.INTCTRL = TCB_CAPT_bm; \ + TCB0.CTRLA = TCB_ENABLE_bm; \ + } + +#elif ( configUSE_TIMER_INSTANCE == 1 ) + + #define TICK_INT_vect TCB1_INT_vect + #define INT_FLAGS TCB1_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB1.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB1.INTCTRL = TCB_CAPT_bm; \ + TCB1.CTRLA = TCB_ENABLE_bm; \ + } + +#elif ( configUSE_TIMER_INSTANCE == 2 ) + + #define TICK_INT_vect TCB2_INT_vect + #define INT_FLAGS TCB2_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB2.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB2.INTCTRL = TCB_CAPT_bm; \ + TCB2.CTRLA = TCB_ENABLE_bm; \ + } + +#elif ( configUSE_TIMER_INSTANCE == 3 ) + + #define TICK_INT_vect TCB3_INT_vect + #define INT_FLAGS TCB3_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB3.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB3.INTCTRL = TCB_CAPT_bm; \ + TCB3.CTRLA = TCB_ENABLE_bm; \ + } + +#elif ( configUSE_TIMER_INSTANCE == 4 ) + + #define TICK_INT_vect TCB4_INT_vect + #define INT_FLAGS TCB4_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB4.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB4.INTCTRL = TCB_CAPT_bm; \ + TCB4.CTRLA = TCB_ENABLE_bm; \ + } + +#elif ( configUSE_TIMER_INSTANCE == 5 ) + + #define TICK_INT_vect RTC_CNT_vect + #define INT_FLAGS RTC_INTFLAGS + #define INT_MASK RTC_OVF_bm + +/* Hertz to period for RTC setup */ + #define RTC_PERIOD_HZ( x ) ( 32768 * ( ( 1.0 / x ) ) ) + #define TICK_init() \ + { \ + while( RTC.STATUS > 0 ) {; } \ + RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \ + RTC.PER = RTC_PERIOD_HZ( configTICK_RATE_HZ ); \ + RTC.INTCTRL |= 1 << RTC_OVF_bp; \ + } + +#else /* if ( configUSE_TIMER_INSTANCE == 0 ) */ + #undef TICK_INT_vect + #undef INT_FLAGS + #undef INT_MASK + #undef TICK_init() + #error Invalid timer setting. +#endif /* if ( configUSE_TIMER_INSTANCE == 0 ) */ + +/*-----------------------------------------------------------*/ + +#endif /* PORTHARDWARE_H */ diff --git a/portable/GCC/AVR_AVRDx/portmacro.h b/portable/GCC/AVR_AVRDx/portmacro.h index f26accaf54..7879b64111 100644 --- a/portable/GCC/AVR_AVRDx/portmacro.h +++ b/portable/GCC/AVR_AVRDx/portmacro.h @@ -35,6 +35,7 @@ #endif /* *INDENT-ON* */ +#include /*----------------------------------------------------------- * Port specific definitions. * @@ -102,6 +103,161 @@ extern void vPortYieldFromISR( void ) __attribute__( ( naked ) ); #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +/* Macros for tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + +extern void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime); +#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime) vPortSuppressTicksAndSleep(xExpectedIdleTime) +#endif + +#ifndef configPRE_PWR_DOWN_PROCESSING +#define configPRE_PWR_DOWN_PROCESSING() +#endif + +#ifndef configPOST_PWR_DOWN_PROCESSING +#define configPOST_PWR_DOWN_PROCESSING() +#endif + +/*-----------------------------------------------------------*/ + +/* Helper macros for portSAVE_CONTEXT/ portRESTORE_CONTEXT - common support for Mega-0 and AVR-Dx families */ + +#if defined(__AVR_HAVE_RAMPZ__) + +#define portSAVE_RAMPZ() \ + asm volatile("in r0, __RAMPZ__ \n\t" \ + "push r0 \n\t"); + +#define portRESTORE_RAMPZ() \ + asm volatile("pop r0 \n\t" \ + "out __RAMPZ__, r0 \n\t"); + +#else + +#define portSAVE_RAMPZ() +#define portRESTORE_RAMPZ() + +#endif + +/* Macro to save all the general purpose registers, the save the stack pointer + * into the TCB. + + * The first thing we do is save the flags then disable interrupts. This is to + * guard our stack against having a context switch interrupt after we have already + * pushed the registers onto the stack - causing the 32 registers to be on the + * stack twice. + + * r1 is set to zero as the compiler expects it to be thus, however some + * of the math routines make use of R1. + + * The interrupts will have been disabled during the call to portSAVE_CONTEXT() + * so we need not worry about reading/writing to the stack pointer. */ + +#define portSAVE_CONTEXT() \ + { \ + asm volatile("push r0 \n\t" \ + "in r0, __SREG__ \n\t" \ + "cli \n\t" \ + "push r0 \n\t"); \ + portSAVE_RAMPZ(); \ + asm volatile("push r1 \n\t" \ + "clr r1 \n\t" \ + "push r2 \n\t" \ + "push r3 \n\t" \ + "push r4 \n\t" \ + "push r5 \n\t" \ + "push r6 \n\t" \ + "push r7 \n\t" \ + "push r8 \n\t" \ + "push r9 \n\t" \ + "push r10 \n\t" \ + "push r11 \n\t" \ + "push r12 \n\t" \ + "push r13 \n\t" \ + "push r14 \n\t" \ + "push r15 \n\t" \ + "push r16 \n\t" \ + "push r17 \n\t" \ + "push r18 \n\t" \ + "push r19 \n\t" \ + "push r20 \n\t" \ + "push r21 \n\t" \ + "push r22 \n\t" \ + "push r23 \n\t" \ + "push r24 \n\t" \ + "push r25 \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "push r28 \n\t" \ + "push r29 \n\t" \ + "push r30 \n\t" \ + "push r31 \n\t" \ + "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "in r0, __SP_L__ \n\t" \ + "st x+, r0 \n\t" \ + "in r0, __SP_H__ \n\t" \ + "st x+, r0 \n\t"); \ + } + +/* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during + * the context save so we can write to the stack pointer. */ +#define portRESTORE_CONTEXT() \ + { \ + asm volatile("lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "ld r28, x+ \n\t" \ + "out __SP_L__, r28 \n\t" \ + "ld r29, x+ \n\t" \ + "out __SP_H__, r29 \n\t" \ + "pop r31 \n\t" \ + "pop r30 \n\t" \ + "pop r29 \n\t" \ + "pop r28 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" \ + "pop r25 \n\t" \ + "pop r24 \n\t" \ + "pop r23 \n\t" \ + "pop r22 \n\t" \ + "pop r21 \n\t" \ + "pop r20 \n\t" \ + "pop r19 \n\t" \ + "pop r18 \n\t" \ + "pop r17 \n\t" \ + "pop r16 \n\t" \ + "pop r15 \n\t" \ + "pop r14 \n\t" \ + "pop r13 \n\t" \ + "pop r12 \n\t" \ + "pop r11 \n\t" \ + "pop r10 \n\t" \ + "pop r9 \n\t" \ + "pop r8 \n\t" \ + "pop r7 \n\t" \ + "pop r6 \n\t" \ + "pop r5 \n\t" \ + "pop r4 \n\t" \ + "pop r3 \n\t" \ + "pop r2 \n\t" \ + "pop r1 \n\t"); \ + portRESTORE_RAMPZ(); \ + asm volatile("pop r0 \n\t" \ + "out __SREG__, r0 \n\t" \ + "pop r0 \n\t"); \ + } +/*-----------------------------------------------------------*/ + +#define portSET_MODE_AND_SLEEP(mode) \ + { \ + set_sleep_mode(mode); \ + sleep_enable(); \ + portENABLE_INTERRUPTS(); \ + sleep_cpu(); \ + portDISABLE_INTERRUPTS(); \ + sleep_disable(); \ + } + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/portable/GCC/AVR_AVRDx/portmacro.h.bak b/portable/GCC/AVR_AVRDx/portmacro.h.bak new file mode 100644 index 0000000000..8f40795114 --- /dev/null +++ b/portable/GCC/AVR_AVRDx/portmacro.h.bak @@ -0,0 +1,112 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +/* *INDENT-OFF* */ + #ifdef __cplusplus + extern "C" { + #endif +/* *INDENT-ON* */ + +#include +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT int +#define portSTACK_TYPE uint8_t +#define portBASE_TYPE char + +#define portPOINTER_SIZE_TYPE uint16_t + +typedef portSTACK_TYPE StackType_t; +typedef signed char BaseType_t; +typedef unsigned char UBaseType_t; + +#if ( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +#define portENTER_CRITICAL() \ + asm volatile ( "in __tmp_reg__, __SREG__" ); \ + asm volatile ( "cli" ); \ + asm volatile ( "push __tmp_reg__" ) + +#define portEXIT_CRITICAL() \ + asm volatile ( "pop __tmp_reg__" ); \ + asm volatile ( "out __SREG__, __tmp_reg__" ) + +#define portDISABLE_INTERRUPTS() asm volatile ( "cli" ::); +#define portENABLE_INTERRUPTS() asm volatile ( "sei" ::); +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 1 +#define portNOP() asm volatile ( "nop" ); +/*-----------------------------------------------------------*/ + +/* Kernel utilities. */ +extern void vPortYield( void ) __attribute__( ( naked ) ); +#define portYIELD() vPortYield() + +extern void vPortYieldFromISR( void ) __attribute__( ( naked ) ); +#define portYIELD_FROM_ISR() vPortYieldFromISR() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) + +/* *INDENT-OFF* */ + #ifdef __cplusplus + } + #endif +/* *INDENT-ON* */ + +#endif /* PORTMACRO_H */ From b42b19cdf615d9921482c3839a8d606774894899 Mon Sep 17 00:00:00 2001 From: Cristian Pop Date: Wed, 28 Jul 2021 09:46:20 +0300 Subject: [PATCH 2/5] Update AVR port files --- portable/GCC/AVR_AVRDx/port.c.bak | 506 ---------------------- portable/GCC/AVR_AVRDx/porthardware.h.bak | 137 ------ portable/GCC/AVR_AVRDx/portmacro.h.bak | 112 ----- 3 files changed, 755 deletions(-) delete mode 100644 portable/GCC/AVR_AVRDx/port.c.bak delete mode 100644 portable/GCC/AVR_AVRDx/porthardware.h.bak delete mode 100644 portable/GCC/AVR_AVRDx/portmacro.h.bak diff --git a/portable/GCC/AVR_AVRDx/port.c.bak b/portable/GCC/AVR_AVRDx/port.c.bak deleted file mode 100644 index 1656fd536c..0000000000 --- a/portable/GCC/AVR_AVRDx/port.c.bak +++ /dev/null @@ -1,506 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#include - -#include -#include "porthardware.h" -#include "FreeRTOS.h" -#include "task.h" - -/*----------------------------------------------------------- -* Implementation of functions defined in portable.h for the AVR port. -*----------------------------------------------------------*/ - -/* Start tasks with interrupts enables. */ -#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 ) - -/*-----------------------------------------------------------*/ - -/* We require the address of the pxCurrentTCB variable, but don't want to know - * any details of its type. */ -typedef void RTOS_TCB_t; -extern volatile RTOS_TCB_t * volatile pxCurrentTCB; - -/*-----------------------------------------------------------*/ - -/* - * Macro to save all the general purpose registers, the save the stack pointer - * into the TCB. - * - * The first thing we do is save the flags then disable interrupts. This is to - * guard our stack against having a context switch interrupt after we have already - * pushed the registers onto the stack - causing the 32 registers to be on the - * stack twice. - * - * r1 is set to zero as the compiler expects it to be thus, however some - * of the math routines make use of R1. - * - * The interrupts will have been disabled during the call to portSAVE_CONTEXT() - * so we need not worry about reading/writing to the stack pointer. - */ - -#define portSAVE_CONTEXT() \ - asm volatile ( "push r0 \n\t" \ - "in r0, __SREG__ \n\t" \ - "cli \n\t" \ - "push r0 \n\t" \ - "in r0, __RAMPZ__ \n\t" \ - "push r0 \n\t" \ - "push r1 \n\t" \ - "clr r1 \n\t" \ - "push r2 \n\t" \ - "push r3 \n\t" \ - "push r4 \n\t" \ - "push r5 \n\t" \ - "push r6 \n\t" \ - "push r7 \n\t" \ - "push r8 \n\t" \ - "push r9 \n\t" \ - "push r10 \n\t" \ - "push r11 \n\t" \ - "push r12 \n\t" \ - "push r13 \n\t" \ - "push r14 \n\t" \ - "push r15 \n\t" \ - "push r16 \n\t" \ - "push r17 \n\t" \ - "push r18 \n\t" \ - "push r19 \n\t" \ - "push r20 \n\t" \ - "push r21 \n\t" \ - "push r22 \n\t" \ - "push r23 \n\t" \ - "push r24 \n\t" \ - "push r25 \n\t" \ - "push r26 \n\t" \ - "push r27 \n\t" \ - "push r28 \n\t" \ - "push r29 \n\t" \ - "push r30 \n\t" \ - "push r31 \n\t" \ - "lds r26, pxCurrentTCB \n\t" \ - "lds r27, pxCurrentTCB + 1 \n\t" \ - "in r0, __SP_L__ \n\t" \ - "st x+, r0 \n\t" \ - "in r0, __SP_H__ \n\t" \ - "st x+, r0 \n\t" ); - -/* - * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during - * the context save so we can write to the stack pointer. - */ - -#define portRESTORE_CONTEXT() \ - asm volatile ( "lds r26, pxCurrentTCB \n\t" \ - "lds r27, pxCurrentTCB + 1 \n\t" \ - "ld r28, x+ \n\t" \ - "out __SP_L__, r28 \n\t" \ - "ld r29, x+ \n\t" \ - "out __SP_H__, r29 \n\t" \ - "pop r31 \n\t" \ - "pop r30 \n\t" \ - "pop r29 \n\t" \ - "pop r28 \n\t" \ - "pop r27 \n\t" \ - "pop r26 \n\t" \ - "pop r25 \n\t" \ - "pop r24 \n\t" \ - "pop r23 \n\t" \ - "pop r22 \n\t" \ - "pop r21 \n\t" \ - "pop r20 \n\t" \ - "pop r19 \n\t" \ - "pop r18 \n\t" \ - "pop r17 \n\t" \ - "pop r16 \n\t" \ - "pop r15 \n\t" \ - "pop r14 \n\t" \ - "pop r13 \n\t" \ - "pop r12 \n\t" \ - "pop r11 \n\t" \ - "pop r10 \n\t" \ - "pop r9 \n\t" \ - "pop r8 \n\t" \ - "pop r7 \n\t" \ - "pop r6 \n\t" \ - "pop r5 \n\t" \ - "pop r4 \n\t" \ - "pop r3 \n\t" \ - "pop r2 \n\t" \ - "pop r1 \n\t" \ - "pop r0 \n\t" \ - "out __RAMPZ__, r0 \n\t" \ - "pop r0 \n\t" \ - "out __SREG__, r0 \n\t" \ - "pop r0 \n\t" ); - -/*-----------------------------------------------------------*/ - -/* - * Perform hardware setup to enable ticks from timer. - */ -static void prvSetupTimerInterrupt( void ); -/*-----------------------------------------------------------*/ - -/* - * See header file for description. - */ -StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, - TaskFunction_t pxCode, - void * pvParameters ) -{ - uint16_t usAddress; - - /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ - - /* Place a few bytes of known values on the bottom of the stack. - * This is just useful for debugging. Uncomment if needed. */ - /* *pxTopOfStack = 0x11; */ - /* pxTopOfStack--; */ - /* *pxTopOfStack = 0x22; */ - /* pxTopOfStack--; */ - /* *pxTopOfStack = 0x33; */ - /* pxTopOfStack--; */ - - /* The start of the task code will be popped off the stack last, so place - * it on first. */ - usAddress = ( uint16_t ) pxCode; - *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff ); - pxTopOfStack--; - - usAddress >>= 8; - *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff ); - pxTopOfStack--; - - /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). - * portSAVE_CONTEXT places the flags on the stack immediately after r0 - * to ensure the interrupts get disabled as soon as possible, and so ensuring - * the stack use is minimal should a context switch interrupt occur. */ - *pxTopOfStack = ( StackType_t ) 0x00; /* R0 */ - pxTopOfStack--; - *pxTopOfStack = portFLAGS_INT_ENABLED; - pxTopOfStack--; -#if defined(__AVR_HAVE_RAMPZ__) - *pxTopOfStack = (StackType_t)0x00; /* RAMPZ */ - pxTopOfStack--; -#endif - - /* Now the remaining registers. The compiler expects R1 to be 0. */ - *pxTopOfStack = ( StackType_t ) 0x00; /* R1 */ - - /* Leave R2 - R23 untouched */ - pxTopOfStack -= 23; - - /* Place the parameter on the stack in the expected location. */ - usAddress = ( uint16_t ) pvParameters; - *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff ); - pxTopOfStack--; - - usAddress >>= 8; - *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff ); - - /* Leave register R26 - R31 untouched */ - pxTopOfStack -= 7; - - /*lint +e950 +e611 +e923 */ - - return pxTopOfStack; -} -/*-----------------------------------------------------------*/ - -BaseType_t xPortStartScheduler( void ) -{ - /* Setup the hardware to generate the tick. */ - prvSetupTimerInterrupt(); - - /* Restore the context of the first task that is going to run. */ - portRESTORE_CONTEXT(); - - /* Simulate a function call end as generated by the compiler. We will now - * jump to the start of the task the context of which we have just restored. */ - asm volatile ( "ret" ); - - /* Should not get here. */ - return pdTRUE; -} -/*-----------------------------------------------------------*/ - -void vPortEndScheduler( void ) -{ - /* vPortEndScheduler is not implemented in this port. */ -} -/*-----------------------------------------------------------*/ - -/* - * Manual context switch. The first thing we do is save the registers so we - * can use a naked attribute. - */ -void vPortYield( void ) __attribute__( ( naked ) ); -void vPortYield( void ) -{ - portSAVE_CONTEXT(); - vTaskSwitchContext(); - portRESTORE_CONTEXT(); - asm volatile ( "ret" ); -} -/*-----------------------------------------------------------*/ - -/* - * Manual context switch callable from ISRs. The first thing - * we do is save the registers so we can use a naked attribute. - */ -void vPortYieldFromISR( void ) __attribute__( ( naked ) ); -void vPortYieldFromISR( void ) -{ - portSAVE_CONTEXT(); - vTaskSwitchContext(); - portRESTORE_CONTEXT(); - asm volatile ( "reti" ); -} -/*-----------------------------------------------------------*/ - -/* - * Context switch function used by the tick. This must be identical to - * vPortYield() from the call to vTaskSwitchContext() onwards. The only - * difference from vPortYield() is the tick count is incremented as the - * call comes from the tick ISR. - */ -void vPortYieldFromTick( void ) __attribute__( ( naked ) ); -void vPortYieldFromTick( void ) -{ - portSAVE_CONTEXT(); - - if( xTaskIncrementTick() != pdFALSE ) - { - vTaskSwitchContext(); - } - - portRESTORE_CONTEXT(); - - asm volatile ( "reti" ); -} -/*-----------------------------------------------------------*/ - -/* - * Setup timer to generate a tick interrupt. - */ -static void prvSetupTimerInterrupt( void ) -{ - /* Configure low-power timer used in tickless mode */ -#if (configUSE_TICKLESS_IDLE == 1) - RTC_INIT(); -#endif - TICK_init(); -} -/*-----------------------------------------------------------*/ - -#if (configUSE_PREEMPTION == 1) - -/* - * Tick ISR for preemptive scheduler. We can use a naked attribute as - * the context is saved at the start of vPortYieldFromTick(). The tick - * count is incremented after the context is saved. - */ - ISR( TICK_INT_vect, ISR_NAKED ) - { - /* Clear tick interrupt flag. */ - CLR_INT( INT_FLAGS, INT_MASK ); - - vPortYieldFromTick(); - - asm volatile ( "reti" ); - } -#else /* if configUSE_PREEMPTION == 1 */ - -/* - * Tick ISR for the cooperative scheduler. All this does is increment the - * tick count. We don't need to switch context, this can only be done by - * manual calls to taskYIELD(); - */ - ISR( TICK_INT_vect ) - { - /* Clear tick interrupt flag. */ - INT_FLAGS = INT_MASK; - xTaskIncrementTick(); - } -#endif /* if configUSE_PREEMPTION == 1 */ - -#if (configUSE_TICKLESS_IDLE == 1) - -volatile uint32_t RTC_OVF_Count = 0; - -ISR(RTC_CNT_vect) -{ - if (RTC.INTFLAGS & RTC_OVF_bm ) - { - RTC_OVF_Count += 0x00010000; - RTC.INTFLAGS = (RTC_OVF_bm); - } - - if (RTC.INTFLAGS & RTC_CMP_bm ) - { - RTC.INTFLAGS = (RTC_CMP_bm); - //Disable compare interrupt - RTC.INTCTRL &= (0xFF ^ RTC_CMP_bm); - } - -} - -static uint32_t ulGetExternalTime(void) -{ - uint32_t time_rtc; - - while (RTC.STATUS & RTC_CNTBUSY_bm) - { - ; - } - time_rtc = RTC.CNT; - time_rtc += RTC_OVF_Count; - return time_rtc; -} - -static void vSetWakeTimeInterrupt(uint16_t xExpectedIdleTime) -{ - uint32_t rtc_cnt_time; - - /* compute the required */ - rtc_cnt_time = RTC_TICKS_TO_COUNTS(xExpectedIdleTime); - rtc_cnt_time += ulGetExternalTime(); - - while (RTC.STATUS & RTC_CMPBUSY_bm) - { - ; - } - RTC.CMP = (rtc_cnt_time & 0xFFFF); - - //Enable compare interrupt - RTC.INTCTRL |= RTC_CMP_bm; -} - -/* Define the function that is called by portSUPPRESS_TICKS_AND_SLEEP(). */ -__attribute__((weak)) void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) -{ - eSleepModeStatus eSleepStatus; - uint32_t ulLowPowerTimeBeforeSleep, ulLowPowerTimeAfterSleep; - - /* Read the current time from a time source that will remain operational - while the microcontroller is in a low power state. */ - ulLowPowerTimeBeforeSleep = ulGetExternalTime(); - - /* Stop the timer that is generating the tick interrupt. */ - TICK_TMR_STOP(); - - /* Enter a critical section that will not effect interrupts bringing the MCU - out of sleep mode. */ - portDISABLE_INTERRUPTS(); - - /* Ensure it is still ok to enter the sleep mode. */ - eSleepStatus = eTaskConfirmSleepModeStatus(); - - if (eSleepStatus == eAbortSleep) - { - /* A task has been moved out of the Blocked state since this macro was - * executed, or a context switch is being held pending. Do not enter a - * sleep state. Restart the tick and exit the critical section. */ - TICK_TMR_START(); - portENABLE_INTERRUPTS(); - } - else - { - if (eSleepStatus == eNoTasksWaitingTimeout) - { - /* A user definable macro that allows application code to be inserted - * here. Such application code can be used to minimize power consumption - * further by turning off IO, peripheral clocks, the Flash, etc. */ - configPRE_PWR_DOWN_PROCESSING(); - - /* There are no running state tasks and no tasks that are blocked with a - * time out. Assuming the application does not care if the tick time slips - * with respect to calendar time then enter a deep sleep that can only be - * woken by (in this demo case) the user button being pushed on the - * Curiosity Nano board. If the application does require the tick time - * to keep better track of the calender time then the PIT peripheral can be - * used to make rough adjustments. */ - portSET_MODE_AND_SLEEP(SLEEP_MODE_PWR_DOWN); - - /* A user definable macro that allows application code to be inserted - * here. Such application code can be used to reverse any actions taken - * by the configPRE_STOP_PROCESSING() */ - configPOST_PWR_DOWN_PROCESSING(); - } - else - { - /* Configure an interrupt to bring the microcontroller out of its low - * power state at the time the kernel next needs to execute. The - * interrupt must be generated from a source that remains operational - * when the microcontroller is in a low power state. */ - vSetWakeTimeInterrupt(xExpectedIdleTime); - - /* Allow the application to define some pre-sleep processing. This is - * the standard configPRE_SLEEP_PROCESSING() macro as described on the - * FreeRTOS.org website. */ - configPRE_SLEEP_PROCESSING(xExpectedIdleTime); - - /* Enter the low power state. */ - portSET_MODE_AND_SLEEP(SLEEP_MODE_STANDBY); - - /* Determine how long the microcontroller was actually in a low power - * state for, which will be less than xExpectedIdleTime if the - * microcontroller was brought out of low power mode by an interrupt - * other than that configured by the vSetWakeTimeInterrupt() call. - * Note that the scheduler is suspended before - * portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when - * portSUPPRESS_TICKS_AND_SLEEP() returns. Therefore no other tasks will - * execute until this function completes. */ - ulLowPowerTimeAfterSleep = ulGetExternalTime(); - - /* Allow the application to define some post sleep processing. This is - * the standard configPOST_SLEEP_PROCESSING() macro, as described on the - * FreeRTOS.org website. - * It can be used to reverse the actions of configPRE_SLEEP_PROCESSING(), - * and in so doing, return the microcontroller back to its fully operational state */ - configPOST_SLEEP_PROCESSING(xExpectedIdleTime); - - /* Correct the kernels tick count to account for the time the - * microcontroller spent in its low power state. */ - vTaskStepTick(RTC_COUNTS_TO_TICKS(ulLowPowerTimeAfterSleep - ulLowPowerTimeBeforeSleep)); - // vTaskStepTick(xExpectedIdleTime); - - } - - /* Exit the critical section - it might be possible to do this immediately - * after the SET_MODE_AND_SLEEP calls. */ - portENABLE_INTERRUPTS(); - - /* Restart the timer that is generating the tick interrupt. */ - TICK_TMR_START(); - } -} - -#endif diff --git a/portable/GCC/AVR_AVRDx/porthardware.h.bak b/portable/GCC/AVR_AVRDx/porthardware.h.bak deleted file mode 100644 index ca0302e324..0000000000 --- a/portable/GCC/AVR_AVRDx/porthardware.h.bak +++ /dev/null @@ -1,137 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef PORTHARDWARE_H -#define PORTHARDWARE_H - -#include "FreeRTOSConfig.h" - -/*-----------------------------------------------------------*/ - -#define CLR_INT( FLAG_REG, FLAG_MASK ) \ - asm volatile ( \ - "push r16\n\t" \ - "ldi r16, %1\n\t" \ - "sts %0, r16\n\t" \ - "pop r16\n\t" \ - : \ - : "i" ( _SFR_MEM_ADDR( FLAG_REG ) ), "i" ( ( uint8_t ) ( FLAG_MASK ) ) \ - ); - -#if ( configUSE_TIMER_INSTANCE == 0 ) - - #define TICK_INT_vect TCB0_INT_vect - #define INT_FLAGS TCB0_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB0.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB0.INTCTRL = TCB_CAPT_bm; \ - TCB0.CTRLA = TCB_ENABLE_bm; \ - } - -#elif ( configUSE_TIMER_INSTANCE == 1 ) - - #define TICK_INT_vect TCB1_INT_vect - #define INT_FLAGS TCB1_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB1.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB1.INTCTRL = TCB_CAPT_bm; \ - TCB1.CTRLA = TCB_ENABLE_bm; \ - } - -#elif ( configUSE_TIMER_INSTANCE == 2 ) - - #define TICK_INT_vect TCB2_INT_vect - #define INT_FLAGS TCB2_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB2.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB2.INTCTRL = TCB_CAPT_bm; \ - TCB2.CTRLA = TCB_ENABLE_bm; \ - } - -#elif ( configUSE_TIMER_INSTANCE == 3 ) - - #define TICK_INT_vect TCB3_INT_vect - #define INT_FLAGS TCB3_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB3.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB3.INTCTRL = TCB_CAPT_bm; \ - TCB3.CTRLA = TCB_ENABLE_bm; \ - } - -#elif ( configUSE_TIMER_INSTANCE == 4 ) - - #define TICK_INT_vect TCB4_INT_vect - #define INT_FLAGS TCB4_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB4.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB4.INTCTRL = TCB_CAPT_bm; \ - TCB4.CTRLA = TCB_ENABLE_bm; \ - } - -#elif ( configUSE_TIMER_INSTANCE == 5 ) - - #define TICK_INT_vect RTC_CNT_vect - #define INT_FLAGS RTC_INTFLAGS - #define INT_MASK RTC_OVF_bm - -/* Hertz to period for RTC setup */ - #define RTC_PERIOD_HZ( x ) ( 32768 * ( ( 1.0 / x ) ) ) - #define TICK_init() \ - { \ - while( RTC.STATUS > 0 ) {; } \ - RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \ - RTC.PER = RTC_PERIOD_HZ( configTICK_RATE_HZ ); \ - RTC.INTCTRL |= 1 << RTC_OVF_bp; \ - } - -#else /* if ( configUSE_TIMER_INSTANCE == 0 ) */ - #undef TICK_INT_vect - #undef INT_FLAGS - #undef INT_MASK - #undef TICK_init() - #error Invalid timer setting. -#endif /* if ( configUSE_TIMER_INSTANCE == 0 ) */ - -/*-----------------------------------------------------------*/ - -#endif /* PORTHARDWARE_H */ diff --git a/portable/GCC/AVR_AVRDx/portmacro.h.bak b/portable/GCC/AVR_AVRDx/portmacro.h.bak deleted file mode 100644 index 8f40795114..0000000000 --- a/portable/GCC/AVR_AVRDx/portmacro.h.bak +++ /dev/null @@ -1,112 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef PORTMACRO_H -#define PORTMACRO_H - -/* *INDENT-OFF* */ - #ifdef __cplusplus - extern "C" { - #endif -/* *INDENT-ON* */ - -#include -/*----------------------------------------------------------- - * Port specific definitions. - * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. - * - * These settings should not be altered. - *----------------------------------------------------------- - */ - -/* Type definitions. */ -#define portCHAR char -#define portFLOAT float -#define portDOUBLE double -#define portLONG long -#define portSHORT int -#define portSTACK_TYPE uint8_t -#define portBASE_TYPE char - -#define portPOINTER_SIZE_TYPE uint16_t - -typedef portSTACK_TYPE StackType_t; -typedef signed char BaseType_t; -typedef unsigned char UBaseType_t; - -#if ( configUSE_16_BIT_TICKS == 1 ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff -#else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL -#endif -/*-----------------------------------------------------------*/ - -/* Critical section management. */ -#define portENTER_CRITICAL() \ - asm volatile ( "in __tmp_reg__, __SREG__" ); \ - asm volatile ( "cli" ); \ - asm volatile ( "push __tmp_reg__" ) - -#define portEXIT_CRITICAL() \ - asm volatile ( "pop __tmp_reg__" ); \ - asm volatile ( "out __SREG__, __tmp_reg__" ) - -#define portDISABLE_INTERRUPTS() asm volatile ( "cli" ::); -#define portENABLE_INTERRUPTS() asm volatile ( "sei" ::); -/*-----------------------------------------------------------*/ - -/* Architecture specifics. */ -#define portSTACK_GROWTH ( -1 ) -#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portBYTE_ALIGNMENT 1 -#define portNOP() asm volatile ( "nop" ); -/*-----------------------------------------------------------*/ - -/* Kernel utilities. */ -extern void vPortYield( void ) __attribute__( ( naked ) ); -#define portYIELD() vPortYield() - -extern void vPortYieldFromISR( void ) __attribute__( ( naked ) ); -#define portYIELD_FROM_ISR() vPortYieldFromISR() -/*-----------------------------------------------------------*/ - -/* Task function macros as described on the FreeRTOS.org WEB site. */ -#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) -#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) - -/* *INDENT-OFF* */ - #ifdef __cplusplus - } - #endif -/* *INDENT-ON* */ - -#endif /* PORTMACRO_H */ From d800d267e9c939d503f4047ef81b007c953aa99d Mon Sep 17 00:00:00 2001 From: Cristian Pop Date: Wed, 28 Jul 2021 09:52:03 +0300 Subject: [PATCH 3/5] Update GCC AVR port files --- portable/GCC/AVR_AVRDx/porthardware.h | 21 -- portable/GCC/AVR_AVRDx/porthardware.h.bak | 221 ++++++++++++++++++ portable/GCC/AVR_Mega0/port.c | 273 +++++++++++++--------- portable/GCC/AVR_Mega0/porthardware.h | 36 +++ portable/GCC/AVR_Mega0/portmacro.h | 168 ++++++++++++- 5 files changed, 582 insertions(+), 137 deletions(-) create mode 100644 portable/GCC/AVR_AVRDx/porthardware.h.bak diff --git a/portable/GCC/AVR_AVRDx/porthardware.h b/portable/GCC/AVR_AVRDx/porthardware.h index 52e3f12935..009686f36a 100644 --- a/portable/GCC/AVR_AVRDx/porthardware.h +++ b/portable/GCC/AVR_AVRDx/porthardware.h @@ -133,27 +133,6 @@ #elif ( configUSE_TIMER_INSTANCE == 4 ) - #define TICK_INT_vect TCB4_INT_vect - #define INT_FLAGS TCB4_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB4.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB4.INTCTRL = TCB_CAPT_bm; \ - TCB4.CTRLA = TCB_ENABLE_bm; \ - } - #define TICK_TMR_STOP() TCB4.CTRLA = 0x00; - #define TICK_TMR_START() \ - { \ - TCB4.INTFLAGS = TCB_CAPT_bm; \ - TCB4.CTRLA = TCB_ENABLE_bm; \ - } - #define TICK_TMR_READ() TCB4.CNT - #define TICK_INT_READY() (TCB4.INTCTRL & TCB_CAPT_bm) - -#elif ( configUSE_TIMER_INSTANCE == 5 ) - #if ( configUSE_TICKLESS_IDLE == 1 ) /* RTC is not supported as tick timer when tickless mode is used */ diff --git a/portable/GCC/AVR_AVRDx/porthardware.h.bak b/portable/GCC/AVR_AVRDx/porthardware.h.bak new file mode 100644 index 0000000000..52e3f12935 --- /dev/null +++ b/portable/GCC/AVR_AVRDx/porthardware.h.bak @@ -0,0 +1,221 @@ +/* + * FreeRTOS Kernel + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef PORTHARDWARE_H +#define PORTHARDWARE_H + +#include "FreeRTOSConfig.h" + +/*-----------------------------------------------------------*/ + +#define CLR_INT( FLAG_REG, FLAG_MASK ) \ + asm volatile ( \ + "push r16\n\t" \ + "ldi r16, %1\n\t" \ + "sts %0, r16\n\t" \ + "pop r16\n\t" \ + : \ + : "i" ( _SFR_MEM_ADDR( FLAG_REG ) ), "i" ( ( uint8_t ) ( FLAG_MASK ) ) \ + ); + +#if ( configUSE_TIMER_INSTANCE == 0 ) + + #define TICK_INT_vect TCB0_INT_vect + #define INT_FLAGS TCB0_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB0.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB0.INTCTRL = TCB_CAPT_bm; \ + TCB0.CTRLA = TCB_ENABLE_bm; \ + } + + #define TICK_TMR_STOP() TCB0.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB0.INTFLAGS = TCB_CAPT_bm; \ + TCB0.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB0.CNT + #define TICK_INT_READY() (TCB0.INTCTRL & TCB_CAPT_bm) + +#elif ( configUSE_TIMER_INSTANCE == 1 ) + + #define TICK_INT_vect TCB1_INT_vect + #define INT_FLAGS TCB1_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB1.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB1.INTCTRL = TCB_CAPT_bm; \ + TCB1.CTRLA = TCB_ENABLE_bm; \ + } + + #define TICK_TMR_STOP() TCB1.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB1.INTFLAGS = TCB_CAPT_bm; \ + TCB1.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB1.CNT + #define TICK_INT_READY() (TCB1.INTCTRL & TCB_CAPT_bm) + +#elif ( configUSE_TIMER_INSTANCE == 2 ) + + #define TICK_INT_vect TCB2_INT_vect + #define INT_FLAGS TCB2_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB2.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB2.INTCTRL = TCB_CAPT_bm; \ + TCB2.CTRLA = TCB_ENABLE_bm; \ + } + + #define TICK_TMR_STOP() TCB2.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB2.INTFLAGS = TCB_CAPT_bm; \ + TCB2.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB2.CNT + #define TICK_INT_READY() (TCB2.INTCTRL & TCB_CAPT_bm) + +#elif ( configUSE_TIMER_INSTANCE == 3 ) + + #define TICK_INT_vect TCB3_INT_vect + #define INT_FLAGS TCB3_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB3.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB3.INTCTRL = TCB_CAPT_bm; \ + TCB3.CTRLA = TCB_ENABLE_bm; \ + } + + #define TICK_TMR_STOP() TCB3.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB3.INTFLAGS = TCB_CAPT_bm; \ + TCB3.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB3.CNT + #define TICK_INT_READY() (TCB3.INTCTRL & TCB_CAPT_bm) + +#elif ( configUSE_TIMER_INSTANCE == 4 ) + + #define TICK_INT_vect TCB4_INT_vect + #define INT_FLAGS TCB4_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB4.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB4.INTCTRL = TCB_CAPT_bm; \ + TCB4.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_STOP() TCB4.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB4.INTFLAGS = TCB_CAPT_bm; \ + TCB4.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB4.CNT + #define TICK_INT_READY() (TCB4.INTCTRL & TCB_CAPT_bm) + +#elif ( configUSE_TIMER_INSTANCE == 5 ) + + #if ( configUSE_TICKLESS_IDLE == 1 ) + + /* RTC is not supported as tick timer when tickless mode is used */ + #error Invalid timer setting. + + #else + + #define TICK_INT_vect RTC_CNT_vect + #define INT_FLAGS RTC_INTFLAGS + #define INT_MASK RTC_OVF_bm + + /* Hertz to period for RTC setup */ + #define RTC_PERIOD_HZ( x ) ( 32768 * ( ( 1.0 / x ) ) ) + #define TICK_init() \ + { \ + while( RTC.STATUS > 0 ) {; } \ + RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \ + RTC.PER = RTC_PERIOD_HZ( configTICK_RATE_HZ ); \ + RTC.INTCTRL |= 1 << RTC_OVF_bp; \ + } + #undef TICK_TMR_STOP() + #undef TICK_TMR_START() + #undef TICK_TMR_READ() + #undef TICK_INT_READY() + #endif + +#else /* if ( configUSE_TIMER_INSTANCE == 0 ) */ + #undef TICK_INT_vect + #undef INT_FLAGS + #undef INT_MASK + #undef TICK_init() + #undef TICK_TMR_STOP() + #undef TICK_TMR_START() + #undef TICK_TMR_READ() + #undef TICK_INT_READY() + #error Invalid timer setting. +#endif /* if ( configUSE_TIMER_INSTANCE == 0 ) */ + +/*-----------------------------------------------------------*/ + + +#if ( configUSE_TICKLESS_IDLE == 1 ) + +#define LOW_POWER_CLOCK (32768UL) + +#define RTC_TICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define RTC_TICKS_TO_COUNTS(tick_cnt) (uint32_t)(((float)(tick_cnt * LOW_POWER_CLOCK)/configTICK_RATE_HZ) - 0.5) +#define RTC_COUNTS_TO_TICKS(counts) (uint32_t)((float)((counts * 1.0) * configTICK_RATE_HZ)/LOW_POWER_CLOCK ) + + +#define RTC_INIT() \ +{ \ + while( RTC.STATUS > 0 ) {; } \ + RTC.PER = 0xFFFF; \ + RTC.CMP = 0x3FFF; \ + RTC.CNT = 0; \ + RTC.INTFLAGS = RTC_OVF_bm | RTC_CMP_bm; \ + RTC.CTRLA = RTC_RUNSTDBY_bm | RTC_PRESCALER_DIV1_gc | RTC_RTCEN_bm ; \ + RTC.INTCTRL = RTC_OVF_bm | RTC_CMP_bm; \ +} + +#endif + + +#endif /* PORTHARDWARE_H */ diff --git a/portable/GCC/AVR_Mega0/port.c b/portable/GCC/AVR_Mega0/port.c index 1e25d132ae..fd3e29303d 100644 --- a/portable/GCC/AVR_Mega0/port.c +++ b/portable/GCC/AVR_Mega0/port.c @@ -49,115 +49,6 @@ extern volatile RTOS_TCB_t * volatile pxCurrentTCB; /*-----------------------------------------------------------*/ -/* - * Macro to save all the general purpose registers, the save the stack pointer - * into the TCB. - * - * The first thing we do is save the flags then disable interrupts. This is to - * guard our stack against having a context switch interrupt after we have already - * pushed the registers onto the stack - causing the 32 registers to be on the - * stack twice. - * - * r1 is set to zero as the compiler expects it to be thus, however some - * of the math routines make use of R1. - * - * The interrupts will have been disabled during the call to portSAVE_CONTEXT() - * so we need not worry about reading/writing to the stack pointer. - */ - -#define portSAVE_CONTEXT() \ - asm volatile ( "push r0 \n\t" \ - "in r0, __SREG__ \n\t" \ - "cli \n\t" \ - "push r0 \n\t" \ - "push r1 \n\t" \ - "clr r1 \n\t" \ - "push r2 \n\t" \ - "push r3 \n\t" \ - "push r4 \n\t" \ - "push r5 \n\t" \ - "push r6 \n\t" \ - "push r7 \n\t" \ - "push r8 \n\t" \ - "push r9 \n\t" \ - "push r10 \n\t" \ - "push r11 \n\t" \ - "push r12 \n\t" \ - "push r13 \n\t" \ - "push r14 \n\t" \ - "push r15 \n\t" \ - "push r16 \n\t" \ - "push r17 \n\t" \ - "push r18 \n\t" \ - "push r19 \n\t" \ - "push r20 \n\t" \ - "push r21 \n\t" \ - "push r22 \n\t" \ - "push r23 \n\t" \ - "push r24 \n\t" \ - "push r25 \n\t" \ - "push r26 \n\t" \ - "push r27 \n\t" \ - "push r28 \n\t" \ - "push r29 \n\t" \ - "push r30 \n\t" \ - "push r31 \n\t" \ - "lds r26, pxCurrentTCB \n\t" \ - "lds r27, pxCurrentTCB + 1 \n\t" \ - "in r0, __SP_L__ \n\t" \ - "st x+, r0 \n\t" \ - "in r0, __SP_H__ \n\t" \ - "st x+, r0 \n\t" ); - -/* - * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during - * the context save so we can write to the stack pointer. - */ - -#define portRESTORE_CONTEXT() \ - asm volatile ( "lds r26, pxCurrentTCB \n\t" \ - "lds r27, pxCurrentTCB + 1 \n\t" \ - "ld r28, x+ \n\t" \ - "out __SP_L__, r28 \n\t" \ - "ld r29, x+ \n\t" \ - "out __SP_H__, r29 \n\t" \ - "pop r31 \n\t" \ - "pop r30 \n\t" \ - "pop r29 \n\t" \ - "pop r28 \n\t" \ - "pop r27 \n\t" \ - "pop r26 \n\t" \ - "pop r25 \n\t" \ - "pop r24 \n\t" \ - "pop r23 \n\t" \ - "pop r22 \n\t" \ - "pop r21 \n\t" \ - "pop r20 \n\t" \ - "pop r19 \n\t" \ - "pop r18 \n\t" \ - "pop r17 \n\t" \ - "pop r16 \n\t" \ - "pop r15 \n\t" \ - "pop r14 \n\t" \ - "pop r13 \n\t" \ - "pop r12 \n\t" \ - "pop r11 \n\t" \ - "pop r10 \n\t" \ - "pop r9 \n\t" \ - "pop r8 \n\t" \ - "pop r7 \n\t" \ - "pop r6 \n\t" \ - "pop r5 \n\t" \ - "pop r4 \n\t" \ - "pop r3 \n\t" \ - "pop r2 \n\t" \ - "pop r1 \n\t" \ - "pop r0 \n\t" \ - "out __SREG__, r0 \n\t" \ - "pop r0 \n\t" ); - -/*-----------------------------------------------------------*/ - /* * Perform hardware setup to enable ticks from timer. */ @@ -202,6 +93,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, pxTopOfStack--; *pxTopOfStack = portFLAGS_INT_ENABLED; pxTopOfStack--; +#if defined(__AVR_HAVE_RAMPZ__) + *pxTopOfStack = (StackType_t)0x00; /* RAMPZ */ + pxTopOfStack--; +#endif /* Now the remaining registers. The compiler expects R1 to be 0. */ *pxTopOfStack = ( StackType_t ) 0x00; /* R1 */ @@ -304,11 +199,15 @@ void vPortYieldFromTick( void ) */ static void prvSetupTimerInterrupt( void ) { + /* Configure low-power timer used in tickless mode */ +#if (configUSE_TICKLESS_IDLE == 1) + RTC_INIT(); +#endif TICK_init(); } /*-----------------------------------------------------------*/ -#if configUSE_PREEMPTION == 1 +#if (configUSE_PREEMPTION == 1) /* * Tick ISR for preemptive scheduler. We can use a naked attribute as @@ -338,3 +237,157 @@ static void prvSetupTimerInterrupt( void ) xTaskIncrementTick(); } #endif /* if configUSE_PREEMPTION == 1 */ + +#if (configUSE_TICKLESS_IDLE == 1) + +volatile uint32_t RTC_OVF_Count = 0; + +ISR(RTC_CNT_vect) +{ + if (RTC.INTFLAGS & RTC_OVF_bm ) + { + RTC_OVF_Count += 0x00010000; + RTC.INTFLAGS = (RTC_OVF_bm); + } + + if (RTC.INTFLAGS & RTC_CMP_bm ) + { + RTC.INTFLAGS = (RTC_CMP_bm); + //Disable compare interrupt + RTC.INTCTRL &= (0xFF ^ RTC_CMP_bm); + } + +} + +static uint32_t ulGetExternalTime(void) +{ + uint32_t time_rtc; + + while (RTC.STATUS & RTC_CNTBUSY_bm) + { + ; + } + time_rtc = RTC.CNT; + time_rtc += RTC_OVF_Count; + return time_rtc; +} + +static void vSetWakeTimeInterrupt(uint16_t xExpectedIdleTime) +{ + uint32_t rtc_cnt_time; + + /* compute the required */ + rtc_cnt_time = RTC_TICKS_TO_COUNTS(xExpectedIdleTime); + rtc_cnt_time += ulGetExternalTime(); + + while (RTC.STATUS & RTC_CMPBUSY_bm) + { + ; + } + RTC.CMP = (rtc_cnt_time & 0xFFFF); + + //Enable compare interrupt + RTC.INTCTRL |= RTC_CMP_bm; +} + +/* Define the function that is called by portSUPPRESS_TICKS_AND_SLEEP(). */ +__attribute__((weak)) void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) +{ + eSleepModeStatus eSleepStatus; + uint32_t ulLowPowerTimeBeforeSleep, ulLowPowerTimeAfterSleep; + + /* Read the current time from a time source that will remain operational + while the microcontroller is in a low power state. */ + ulLowPowerTimeBeforeSleep = ulGetExternalTime(); + + /* Stop the timer that is generating the tick interrupt. */ + TICK_TMR_STOP(); + + /* Enter a critical section that will not effect interrupts bringing the MCU + out of sleep mode. */ + portDISABLE_INTERRUPTS(); + + /* Ensure it is still ok to enter the sleep mode. */ + eSleepStatus = eTaskConfirmSleepModeStatus(); + + if (eSleepStatus == eAbortSleep) + { + /* A task has been moved out of the Blocked state since this macro was + * executed, or a context switch is being held pending. Do not enter a + * sleep state. Restart the tick and exit the critical section. */ + TICK_TMR_START(); + portENABLE_INTERRUPTS(); + } + else + { + if (eSleepStatus == eNoTasksWaitingTimeout) + { + /* A user definable macro that allows application code to be inserted + * here. Such application code can be used to minimize power consumption + * further by turning off IO, peripheral clocks, the Flash, etc. */ + configPRE_PWR_DOWN_PROCESSING(); + + /* There are no running state tasks and no tasks that are blocked with a + * time out. Assuming the application does not care if the tick time slips + * with respect to calendar time then enter a deep sleep that can only be + * woken by (in this demo case) the user button being pushed on the + * Curiosity Nano board. If the application does require the tick time + * to keep better track of the calender time then the PIT peripheral can be + * used to make rough adjustments. */ + portSET_MODE_AND_SLEEP(SLEEP_MODE_PWR_DOWN); + + /* A user definable macro that allows application code to be inserted + * here. Such application code can be used to reverse any actions taken + * by the configPRE_STOP_PROCESSING() */ + configPOST_PWR_DOWN_PROCESSING(); + } + else + { + /* Configure an interrupt to bring the microcontroller out of its low + * power state at the time the kernel next needs to execute. The + * interrupt must be generated from a source that remains operational + * when the microcontroller is in a low power state. */ + vSetWakeTimeInterrupt(xExpectedIdleTime); + + /* Allow the application to define some pre-sleep processing. This is + * the standard configPRE_SLEEP_PROCESSING() macro as described on the + * FreeRTOS.org website. */ + configPRE_SLEEP_PROCESSING(xExpectedIdleTime); + + /* Enter the low power state. */ + portSET_MODE_AND_SLEEP(SLEEP_MODE_STANDBY); + + /* Determine how long the microcontroller was actually in a low power + * state for, which will be less than xExpectedIdleTime if the + * microcontroller was brought out of low power mode by an interrupt + * other than that configured by the vSetWakeTimeInterrupt() call. + * Note that the scheduler is suspended before + * portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when + * portSUPPRESS_TICKS_AND_SLEEP() returns. Therefore no other tasks will + * execute until this function completes. */ + ulLowPowerTimeAfterSleep = ulGetExternalTime(); + + /* Allow the application to define some post sleep processing. This is + * the standard configPOST_SLEEP_PROCESSING() macro, as described on the + * FreeRTOS.org website. + * It can be used to reverse the actions of configPRE_SLEEP_PROCESSING(), + * and in so doing, return the microcontroller back to its fully operational state */ + configPOST_SLEEP_PROCESSING(xExpectedIdleTime); + + /* Correct the kernels tick count to account for the time the + * microcontroller spent in its low power state. */ + vTaskStepTick(RTC_COUNTS_TO_TICKS(ulLowPowerTimeAfterSleep - ulLowPowerTimeBeforeSleep)); + // vTaskStepTick(xExpectedIdleTime); + + } + + /* Exit the critical section - it might be possible to do this immediately + * after the SET_MODE_AND_SLEEP calls. */ + portENABLE_INTERRUPTS(); + + /* Restart the timer that is generating the tick interrupt. */ + TICK_TMR_START(); + } +} + +#endif diff --git a/portable/GCC/AVR_Mega0/porthardware.h b/portable/GCC/AVR_Mega0/porthardware.h index 758d9496d7..2dae497306 100644 --- a/portable/GCC/AVR_Mega0/porthardware.h +++ b/portable/GCC/AVR_Mega0/porthardware.h @@ -55,6 +55,15 @@ TCB0.INTCTRL = TCB_CAPT_bm; \ TCB0.CTRLA = TCB_ENABLE_bm; \ } + + #define TICK_TMR_STOP() TCB0.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB0.INTFLAGS = TCB_CAPT_bm; \ + TCB0.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB0.CNT + #define TICK_INT_READY() (TCB0.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 1 ) @@ -68,6 +77,15 @@ TCB1.INTCTRL = TCB_CAPT_bm; \ TCB1.CTRLA = TCB_ENABLE_bm; \ } + + #define TICK_TMR_STOP() TCB1.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB1.INTFLAGS = TCB_CAPT_bm; \ + TCB1.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB1.CNT + #define TICK_INT_READY() (TCB1.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 2 ) @@ -81,6 +99,15 @@ TCB2.INTCTRL = TCB_CAPT_bm; \ TCB2.CTRLA = TCB_ENABLE_bm; \ } + + #define TICK_TMR_STOP() TCB2.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB2.INTFLAGS = TCB_CAPT_bm; \ + TCB2.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB2.CNT + #define TICK_INT_READY() (TCB2.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 3 ) @@ -94,6 +121,15 @@ TCB3.INTCTRL = TCB_CAPT_bm; \ TCB3.CTRLA = TCB_ENABLE_bm; \ } + + #define TICK_TMR_STOP() TCB3.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB3.INTFLAGS = TCB_CAPT_bm; \ + TCB3.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB3.CNT + #define TICK_INT_READY() (TCB3.INTCTRL & TCB_CAPT_bm) #elif ( configUSE_TIMER_INSTANCE == 4 ) diff --git a/portable/GCC/AVR_Mega0/portmacro.h b/portable/GCC/AVR_Mega0/portmacro.h index 7d66a735a0..7879b64111 100644 --- a/portable/GCC/AVR_Mega0/portmacro.h +++ b/portable/GCC/AVR_Mega0/portmacro.h @@ -30,11 +30,12 @@ #define PORTMACRO_H /* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif + #ifdef __cplusplus + extern "C" { + #endif /* *INDENT-ON* */ +#include /*----------------------------------------------------------- * Port specific definitions. * @@ -102,10 +103,165 @@ extern void vPortYieldFromISR( void ) __attribute__( ( naked ) ); #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) -/* *INDENT-OFF* */ -#ifdef __cplusplus - } +/* Macros for tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + +extern void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime); +#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime) vPortSuppressTicksAndSleep(xExpectedIdleTime) +#endif + +#ifndef configPRE_PWR_DOWN_PROCESSING +#define configPRE_PWR_DOWN_PROCESSING() +#endif + +#ifndef configPOST_PWR_DOWN_PROCESSING +#define configPOST_PWR_DOWN_PROCESSING() +#endif + +/*-----------------------------------------------------------*/ + +/* Helper macros for portSAVE_CONTEXT/ portRESTORE_CONTEXT - common support for Mega-0 and AVR-Dx families */ + +#if defined(__AVR_HAVE_RAMPZ__) + +#define portSAVE_RAMPZ() \ + asm volatile("in r0, __RAMPZ__ \n\t" \ + "push r0 \n\t"); + +#define portRESTORE_RAMPZ() \ + asm volatile("pop r0 \n\t" \ + "out __RAMPZ__, r0 \n\t"); + +#else + +#define portSAVE_RAMPZ() +#define portRESTORE_RAMPZ() + #endif + +/* Macro to save all the general purpose registers, the save the stack pointer + * into the TCB. + + * The first thing we do is save the flags then disable interrupts. This is to + * guard our stack against having a context switch interrupt after we have already + * pushed the registers onto the stack - causing the 32 registers to be on the + * stack twice. + + * r1 is set to zero as the compiler expects it to be thus, however some + * of the math routines make use of R1. + + * The interrupts will have been disabled during the call to portSAVE_CONTEXT() + * so we need not worry about reading/writing to the stack pointer. */ + +#define portSAVE_CONTEXT() \ + { \ + asm volatile("push r0 \n\t" \ + "in r0, __SREG__ \n\t" \ + "cli \n\t" \ + "push r0 \n\t"); \ + portSAVE_RAMPZ(); \ + asm volatile("push r1 \n\t" \ + "clr r1 \n\t" \ + "push r2 \n\t" \ + "push r3 \n\t" \ + "push r4 \n\t" \ + "push r5 \n\t" \ + "push r6 \n\t" \ + "push r7 \n\t" \ + "push r8 \n\t" \ + "push r9 \n\t" \ + "push r10 \n\t" \ + "push r11 \n\t" \ + "push r12 \n\t" \ + "push r13 \n\t" \ + "push r14 \n\t" \ + "push r15 \n\t" \ + "push r16 \n\t" \ + "push r17 \n\t" \ + "push r18 \n\t" \ + "push r19 \n\t" \ + "push r20 \n\t" \ + "push r21 \n\t" \ + "push r22 \n\t" \ + "push r23 \n\t" \ + "push r24 \n\t" \ + "push r25 \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "push r28 \n\t" \ + "push r29 \n\t" \ + "push r30 \n\t" \ + "push r31 \n\t" \ + "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "in r0, __SP_L__ \n\t" \ + "st x+, r0 \n\t" \ + "in r0, __SP_H__ \n\t" \ + "st x+, r0 \n\t"); \ + } + +/* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during + * the context save so we can write to the stack pointer. */ +#define portRESTORE_CONTEXT() \ + { \ + asm volatile("lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "ld r28, x+ \n\t" \ + "out __SP_L__, r28 \n\t" \ + "ld r29, x+ \n\t" \ + "out __SP_H__, r29 \n\t" \ + "pop r31 \n\t" \ + "pop r30 \n\t" \ + "pop r29 \n\t" \ + "pop r28 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" \ + "pop r25 \n\t" \ + "pop r24 \n\t" \ + "pop r23 \n\t" \ + "pop r22 \n\t" \ + "pop r21 \n\t" \ + "pop r20 \n\t" \ + "pop r19 \n\t" \ + "pop r18 \n\t" \ + "pop r17 \n\t" \ + "pop r16 \n\t" \ + "pop r15 \n\t" \ + "pop r14 \n\t" \ + "pop r13 \n\t" \ + "pop r12 \n\t" \ + "pop r11 \n\t" \ + "pop r10 \n\t" \ + "pop r9 \n\t" \ + "pop r8 \n\t" \ + "pop r7 \n\t" \ + "pop r6 \n\t" \ + "pop r5 \n\t" \ + "pop r4 \n\t" \ + "pop r3 \n\t" \ + "pop r2 \n\t" \ + "pop r1 \n\t"); \ + portRESTORE_RAMPZ(); \ + asm volatile("pop r0 \n\t" \ + "out __SREG__, r0 \n\t" \ + "pop r0 \n\t"); \ + } +/*-----------------------------------------------------------*/ + +#define portSET_MODE_AND_SLEEP(mode) \ + { \ + set_sleep_mode(mode); \ + sleep_enable(); \ + portENABLE_INTERRUPTS(); \ + sleep_cpu(); \ + portDISABLE_INTERRUPTS(); \ + sleep_disable(); \ + } + +/* *INDENT-OFF* */ + #ifdef __cplusplus + } + #endif /* *INDENT-ON* */ #endif /* PORTMACRO_H */ From f7e0e0d32f35ad7b38554fd652e38ba54dd8a911 Mon Sep 17 00:00:00 2001 From: Cristian Pop Date: Wed, 28 Jul 2021 09:53:55 +0300 Subject: [PATCH 4/5] Update GCC AVR port files --- portable/GCC/AVR_AVRDx/porthardware.h | 21 ++ portable/GCC/AVR_AVRDx/porthardware.h.bak | 221 ---------------------- 2 files changed, 21 insertions(+), 221 deletions(-) delete mode 100644 portable/GCC/AVR_AVRDx/porthardware.h.bak diff --git a/portable/GCC/AVR_AVRDx/porthardware.h b/portable/GCC/AVR_AVRDx/porthardware.h index 009686f36a..52e3f12935 100644 --- a/portable/GCC/AVR_AVRDx/porthardware.h +++ b/portable/GCC/AVR_AVRDx/porthardware.h @@ -133,6 +133,27 @@ #elif ( configUSE_TIMER_INSTANCE == 4 ) + #define TICK_INT_vect TCB4_INT_vect + #define INT_FLAGS TCB4_INTFLAGS + #define INT_MASK TCB_CAPT_bm + + #define TICK_init() \ + { \ + TCB4.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ + TCB4.INTCTRL = TCB_CAPT_bm; \ + TCB4.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_STOP() TCB4.CTRLA = 0x00; + #define TICK_TMR_START() \ + { \ + TCB4.INTFLAGS = TCB_CAPT_bm; \ + TCB4.CTRLA = TCB_ENABLE_bm; \ + } + #define TICK_TMR_READ() TCB4.CNT + #define TICK_INT_READY() (TCB4.INTCTRL & TCB_CAPT_bm) + +#elif ( configUSE_TIMER_INSTANCE == 5 ) + #if ( configUSE_TICKLESS_IDLE == 1 ) /* RTC is not supported as tick timer when tickless mode is used */ diff --git a/portable/GCC/AVR_AVRDx/porthardware.h.bak b/portable/GCC/AVR_AVRDx/porthardware.h.bak deleted file mode 100644 index 52e3f12935..0000000000 --- a/portable/GCC/AVR_AVRDx/porthardware.h.bak +++ /dev/null @@ -1,221 +0,0 @@ -/* - * FreeRTOS Kernel - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef PORTHARDWARE_H -#define PORTHARDWARE_H - -#include "FreeRTOSConfig.h" - -/*-----------------------------------------------------------*/ - -#define CLR_INT( FLAG_REG, FLAG_MASK ) \ - asm volatile ( \ - "push r16\n\t" \ - "ldi r16, %1\n\t" \ - "sts %0, r16\n\t" \ - "pop r16\n\t" \ - : \ - : "i" ( _SFR_MEM_ADDR( FLAG_REG ) ), "i" ( ( uint8_t ) ( FLAG_MASK ) ) \ - ); - -#if ( configUSE_TIMER_INSTANCE == 0 ) - - #define TICK_INT_vect TCB0_INT_vect - #define INT_FLAGS TCB0_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB0.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB0.INTCTRL = TCB_CAPT_bm; \ - TCB0.CTRLA = TCB_ENABLE_bm; \ - } - - #define TICK_TMR_STOP() TCB0.CTRLA = 0x00; - #define TICK_TMR_START() \ - { \ - TCB0.INTFLAGS = TCB_CAPT_bm; \ - TCB0.CTRLA = TCB_ENABLE_bm; \ - } - #define TICK_TMR_READ() TCB0.CNT - #define TICK_INT_READY() (TCB0.INTCTRL & TCB_CAPT_bm) - -#elif ( configUSE_TIMER_INSTANCE == 1 ) - - #define TICK_INT_vect TCB1_INT_vect - #define INT_FLAGS TCB1_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB1.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB1.INTCTRL = TCB_CAPT_bm; \ - TCB1.CTRLA = TCB_ENABLE_bm; \ - } - - #define TICK_TMR_STOP() TCB1.CTRLA = 0x00; - #define TICK_TMR_START() \ - { \ - TCB1.INTFLAGS = TCB_CAPT_bm; \ - TCB1.CTRLA = TCB_ENABLE_bm; \ - } - #define TICK_TMR_READ() TCB1.CNT - #define TICK_INT_READY() (TCB1.INTCTRL & TCB_CAPT_bm) - -#elif ( configUSE_TIMER_INSTANCE == 2 ) - - #define TICK_INT_vect TCB2_INT_vect - #define INT_FLAGS TCB2_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB2.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB2.INTCTRL = TCB_CAPT_bm; \ - TCB2.CTRLA = TCB_ENABLE_bm; \ - } - - #define TICK_TMR_STOP() TCB2.CTRLA = 0x00; - #define TICK_TMR_START() \ - { \ - TCB2.INTFLAGS = TCB_CAPT_bm; \ - TCB2.CTRLA = TCB_ENABLE_bm; \ - } - #define TICK_TMR_READ() TCB2.CNT - #define TICK_INT_READY() (TCB2.INTCTRL & TCB_CAPT_bm) - -#elif ( configUSE_TIMER_INSTANCE == 3 ) - - #define TICK_INT_vect TCB3_INT_vect - #define INT_FLAGS TCB3_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB3.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB3.INTCTRL = TCB_CAPT_bm; \ - TCB3.CTRLA = TCB_ENABLE_bm; \ - } - - #define TICK_TMR_STOP() TCB3.CTRLA = 0x00; - #define TICK_TMR_START() \ - { \ - TCB3.INTFLAGS = TCB_CAPT_bm; \ - TCB3.CTRLA = TCB_ENABLE_bm; \ - } - #define TICK_TMR_READ() TCB3.CNT - #define TICK_INT_READY() (TCB3.INTCTRL & TCB_CAPT_bm) - -#elif ( configUSE_TIMER_INSTANCE == 4 ) - - #define TICK_INT_vect TCB4_INT_vect - #define INT_FLAGS TCB4_INTFLAGS - #define INT_MASK TCB_CAPT_bm - - #define TICK_init() \ - { \ - TCB4.CCMP = configCPU_CLOCK_HZ / configTICK_RATE_HZ; \ - TCB4.INTCTRL = TCB_CAPT_bm; \ - TCB4.CTRLA = TCB_ENABLE_bm; \ - } - #define TICK_TMR_STOP() TCB4.CTRLA = 0x00; - #define TICK_TMR_START() \ - { \ - TCB4.INTFLAGS = TCB_CAPT_bm; \ - TCB4.CTRLA = TCB_ENABLE_bm; \ - } - #define TICK_TMR_READ() TCB4.CNT - #define TICK_INT_READY() (TCB4.INTCTRL & TCB_CAPT_bm) - -#elif ( configUSE_TIMER_INSTANCE == 5 ) - - #if ( configUSE_TICKLESS_IDLE == 1 ) - - /* RTC is not supported as tick timer when tickless mode is used */ - #error Invalid timer setting. - - #else - - #define TICK_INT_vect RTC_CNT_vect - #define INT_FLAGS RTC_INTFLAGS - #define INT_MASK RTC_OVF_bm - - /* Hertz to period for RTC setup */ - #define RTC_PERIOD_HZ( x ) ( 32768 * ( ( 1.0 / x ) ) ) - #define TICK_init() \ - { \ - while( RTC.STATUS > 0 ) {; } \ - RTC.CTRLA = RTC_PRESCALER_DIV1_gc | 1 << RTC_RTCEN_bp; \ - RTC.PER = RTC_PERIOD_HZ( configTICK_RATE_HZ ); \ - RTC.INTCTRL |= 1 << RTC_OVF_bp; \ - } - #undef TICK_TMR_STOP() - #undef TICK_TMR_START() - #undef TICK_TMR_READ() - #undef TICK_INT_READY() - #endif - -#else /* if ( configUSE_TIMER_INSTANCE == 0 ) */ - #undef TICK_INT_vect - #undef INT_FLAGS - #undef INT_MASK - #undef TICK_init() - #undef TICK_TMR_STOP() - #undef TICK_TMR_START() - #undef TICK_TMR_READ() - #undef TICK_INT_READY() - #error Invalid timer setting. -#endif /* if ( configUSE_TIMER_INSTANCE == 0 ) */ - -/*-----------------------------------------------------------*/ - - -#if ( configUSE_TICKLESS_IDLE == 1 ) - -#define LOW_POWER_CLOCK (32768UL) - -#define RTC_TICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define RTC_TICKS_TO_COUNTS(tick_cnt) (uint32_t)(((float)(tick_cnt * LOW_POWER_CLOCK)/configTICK_RATE_HZ) - 0.5) -#define RTC_COUNTS_TO_TICKS(counts) (uint32_t)((float)((counts * 1.0) * configTICK_RATE_HZ)/LOW_POWER_CLOCK ) - - -#define RTC_INIT() \ -{ \ - while( RTC.STATUS > 0 ) {; } \ - RTC.PER = 0xFFFF; \ - RTC.CMP = 0x3FFF; \ - RTC.CNT = 0; \ - RTC.INTFLAGS = RTC_OVF_bm | RTC_CMP_bm; \ - RTC.CTRLA = RTC_RUNSTDBY_bm | RTC_PRESCALER_DIV1_gc | RTC_RTCEN_bm ; \ - RTC.INTCTRL = RTC_OVF_bm | RTC_CMP_bm; \ -} - -#endif - - -#endif /* PORTHARDWARE_H */ From c57656156d827c8813bb849521105db7ac9953b3 Mon Sep 17 00:00:00 2001 From: Cristian Pop Date: Wed, 28 Jul 2021 12:56:56 +0300 Subject: [PATCH 5/5] Update AVR_Mega0 portable files --- portable/GCC/AVR_Mega0/porthardware.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/portable/GCC/AVR_Mega0/porthardware.h b/portable/GCC/AVR_Mega0/porthardware.h index 2dae497306..05a04aee95 100644 --- a/portable/GCC/AVR_Mega0/porthardware.h +++ b/portable/GCC/AVR_Mega0/porthardware.h @@ -155,6 +155,29 @@ #error Invalid timer setting. #endif /* if ( configUSE_TIMER_INSTANCE == 0 ) */ + +#if ( configUSE_TICKLESS_IDLE == 1 ) + +#define LOW_POWER_CLOCK (32768UL) + +#define RTC_TICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define RTC_TICKS_TO_COUNTS(tick_cnt) (uint32_t)(((float)(tick_cnt * LOW_POWER_CLOCK)/configTICK_RATE_HZ) - 0.5) +#define RTC_COUNTS_TO_TICKS(counts) (uint32_t)((float)((counts * 1.0) * configTICK_RATE_HZ)/LOW_POWER_CLOCK ) + + +#define RTC_INIT() \ +{ \ + while( RTC.STATUS > 0 ) {; } \ + RTC.PER = 0xFFFF; \ + RTC.CMP = 0x3FFF; \ + RTC.CNT = 0; \ + RTC.INTFLAGS = RTC_OVF_bm | RTC_CMP_bm; \ + RTC.CTRLA = RTC_RUNSTDBY_bm | RTC_PRESCALER_DIV1_gc | RTC_RTCEN_bm ; \ + RTC.INTCTRL = RTC_OVF_bm | RTC_CMP_bm; \ +} + +#endif + /*-----------------------------------------------------------*/ #endif /* PORTHARDWARE_H */